我是Haskell的新手,我试图实现一个接受“null”参数的head函数版本
safeHead :: Maybe [a] -> Maybe b
safeHead (Just []) = Nothing
safeHead Nothing = Nothing
safeHead (Just (x:xs)) = Just x
字符串
从概念上看,它看起来没问题。但是类型系统不接受最新的等式。为什么?
• Couldn't match expected type ‘b’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for:
safeHead :: forall a b. Maybe [a] -> Maybe b
at ch04.hs:2:1-32
‘b’ is a rigid type variable bound by
the type signature for:
safeHead :: forall a b. Maybe [a] -> Maybe b
at ch04.hs:2:1-32
• In the first argument of ‘Just’, namely ‘x’
In the expression: Just x
In an equation for ‘safeHead’: safeHead (Just (x : xs)) = Just x
• Relevant bindings include
xs :: [a] (bound at ch04.hs:4:19)
x :: a (bound at ch04.hs:4:17)
safeHead :: Maybe [a] -> Maybe b (bound at ch04.hs:3:1)
型
3条答案
按热度按时间n53p2ov01#
类型签名中的类型变量,如
a
和b
字符串
是由函数 caller 选择的。这意味着如果有人调用你的函数,他们可以选择使用它,就好像它是,比如说,
型
在这种情况下,呼叫者对您的第三个等式不满意
型
因为
x
是String
,而不是类型签名所暗示的Int
。为了修复代码,我们需要弱化类型承诺:函数不会为所有
b
返回Maybe b
,而只为b = a
返回。型
最后,请注意,通常这种“安全头”函数是用类型
[a] -> Maybe a
定义的。我想知道是否真的需要输入上的额外Maybe
。额外的Maybe
没有问题--但它可能不是您实际需要的。ewm0tg9j2#
它几乎是正确的,除了类型。结果是
Maybe a
,因为我们取列表的第一项:字符串
我们还可以通过以下方式简化实现:
型
9ceoxa923#
safeHead
函数所关注的安全问题是接收一个空列表作为输入,无论它是否被 Package 为Just
值。参数类型仍然是[a]
;只有返回类型从a
提升到Maybe a
。字符串
在
Maybe [a]
值上使用safeHead
(例如,由safeTail
函数返回)是通过使用Maybe
的Monad
示例完成的。型
然后
型