使用字符串时 S.min 的错误答案
Wrong answer from S.min when strings used
S.min ('1') ('02') =>'02'
为什么这可能呢? (是的类型强制......但这是避难所)
是否可以配置 Sanctuary,以便在使用字符串时不返回任何内容?
有没有一种优雅的方式来处理这个问题?
让我们考虑S.min
的类型:
min :: Ord a => a -> a -> a
String
满足Ord的要求,所以String -> String -> String
是一种可能的特化:
> S.min ('foo') ('bar')
'bar'
如果您处理的输入 应该 是数字但可能不是,最好的方法是预先处理不确定性:
// untrustedInput1 :: Any
// untrustedInput2 :: Any
// input1 :: Maybe Number
const input1 = S.filter (S.is ($.Number)) (S.Just (untrustedInput1));
// input2 :: Maybe Number
const input2 = S.filter (S.is ($.Number)) (S.Just (untrustedInput2));
然后,您可以使用 S.lift2
将 S.min
转换为可以对 Maybe Number
值进行操作的函数:
S.lift2 (S.min) :: (Apply f, Ord a) => f a -> f a -> f a
上面的签名可以像这样专门化:
S.lift2 (S.min) :: Maybe Number -> Maybe Number -> Maybe Number
最后一步是将 S.lift2 (S.min)
应用于可信输入:
S.lift2 (S.min) (input1) (input2)
这是一个完整的工作示例:
> S.lift2 (S.min)
. (S.filter (S.is ($.Number)) (S.Just ('1')))
. (S.filter (S.is ($.Number)) (S.Just ('02')))
Nothing
S.min ('1') ('02') =>'02'
为什么这可能呢? (是的类型强制......但这是避难所) 是否可以配置 Sanctuary,以便在使用字符串时不返回任何内容? 有没有一种优雅的方式来处理这个问题?
让我们考虑S.min
的类型:
min :: Ord a => a -> a -> a
String
满足Ord的要求,所以String -> String -> String
是一种可能的特化:
> S.min ('foo') ('bar')
'bar'
如果您处理的输入 应该 是数字但可能不是,最好的方法是预先处理不确定性:
// untrustedInput1 :: Any
// untrustedInput2 :: Any
// input1 :: Maybe Number
const input1 = S.filter (S.is ($.Number)) (S.Just (untrustedInput1));
// input2 :: Maybe Number
const input2 = S.filter (S.is ($.Number)) (S.Just (untrustedInput2));
然后,您可以使用 S.lift2
将 S.min
转换为可以对 Maybe Number
值进行操作的函数:
S.lift2 (S.min) :: (Apply f, Ord a) => f a -> f a -> f a
上面的签名可以像这样专门化:
S.lift2 (S.min) :: Maybe Number -> Maybe Number -> Maybe Number
最后一步是将 S.lift2 (S.min)
应用于可信输入:
S.lift2 (S.min) (input1) (input2)
这是一个完整的工作示例:
> S.lift2 (S.min)
. (S.filter (S.is ($.Number)) (S.Just ('1')))
. (S.filter (S.is ($.Number)) (S.Just ('02')))
Nothing