我正在尝试编写一个返回列表中第一项的Haskell函数.
h [] = Nothing
h (x:xs) = x
Run Code Online (Sandbox Code Playgroud)
当我用空列表调用它时:
main = print (h [])
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
prog.hs:4:8:
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Show Double -- Defined in `GHC.Float'
instance Show Float -- Defined in `GHC.Float'
instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 23 others
In the expression: print (h [])
In an equation for `main': main = print (h [])
Run Code Online (Sandbox Code Playgroud)
当我给函数列出空列表时,我希望结果为Nothing.
Dan*_*zer 16
这里有一些问题,让我们首先添加一个合理的类型签名
h :: [a] -> Maybe a
h [] = Nothing
h (x:xs) = x
Run Code Online (Sandbox Code Playgroud)
现在我们得到一个错误,我们返回一个平原,x所以x需要类型Maybe a.我们可能不希望这样,所以我们将它包装在Just构造函数中
h (x:_) = Just x
Run Code Online (Sandbox Code Playgroud)
现在问你的问题.
请注意,这不是特定于您的功能,结果
main = print $ head []
main = print $ id []
main = print $ tail []
Run Code Online (Sandbox Code Playgroud)
都是一样的.
类型[]是[a].由于我们没有指定什么a类型h []的Show a => Maybe a.额外的内容Show是因为我们想要打印我们的结果.但我们实际上并没有说明aGHC因为无法违约而感到愤怒.
有两种方法可以解决它,愚蠢的方法是使h单形(单态化?)h
h :: [Int] -> Maybe Int -- Bad
Run Code Online (Sandbox Code Playgroud)
更智能的方法是在我们的呼叫站点简单地选择具体类型.
main = print $ h ([] :: [Int])
Run Code Online (Sandbox Code Playgroud)
我选择Int没有特别的原因,这并不重要.现在Maybe Int是可打印的,所以我们都准备好了.该::语法的工作原理相同,因为它确实为顶级组件,只是声明的类型[]在我们的表达[Int].
有趣的是,GHCi比GHC更具侵略性.这意味着
main = print []
Run Code Online (Sandbox Code Playgroud)
在GHCi中是合法的,但在GHC中则不合法.如果您遇到了有趣的行为,请询问表达式的类型以查看默认值
:t []
Run Code Online (Sandbox Code Playgroud)