Haskell中带可空列表参数的safeHead函数类型错误问题
Haskell safeHead 类型错误原因解析
你的实现代码:
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)
错误原因
问题出在类型签名的定义上:
- 你写的
safeHead :: Maybe [a] -> Maybe b里,a和b是两个完全独立的多态类型变量,这意味着调用者可以随意指定返回值的类型b,比如传入Maybe [Int]却要求返回Maybe String。 - 但你最后一行代码返回的
Just x中,x是输入列表的元素类型a,Haskell作为强类型语言,不允许这种无关联的类型强制匹配,类型系统无法将a自动转换成任意的b,因此抛出类型不匹配的错误。
修正方案
把类型签名中的返回类型改成Maybe a,让返回值的类型和输入列表的元素类型保持一致:
safeHead :: Maybe [a] -> Maybe a safeHead (Just []) = Nothing safeHead Nothing = Nothing safeHead (Just (x:xs)) = Just x
此时Just x的类型是Maybe a,和函数的返回类型完全匹配,类型系统就会接受这个实现。
内容的提问来源于stack exchange,提问作者creatldd1
相关产品推荐
相关产品推荐

