main = do
putStrLn $myLast [1,2,3,4]
myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs
当我尝试运行此代码时,我收到此消息:
“没有由文字 '1' 引起的 (Num String) 实例可能的修复:为 (Num String) 添加实例声明”
当我使用列表 ["1","2","3,"4"] 运行时,它运行良好。我没有指定类型,但它不适用于整数。
main = do
putStrLn $myLast [1,2,3,4]
myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs
当我尝试运行此代码时,我收到此消息:
“没有由文字 '1' 引起的 (Num String) 实例可能的修复:为 (Num String) 添加实例声明”
当我使用列表 ["1","2","3,"4"] 运行时,它运行良好。我没有指定类型,但它不适用于整数。
“没有实例...”错误消息通常具有误导性。
你遇到的问题就是这个
前奏>:t putStrLn
putStrLn::String -> IO()
即该函数只能处理字符串,不能处理数字。一个常见的解决方案是首先将您想要显示的内容转换为字符串:putStrLn (show x)
,但实际上该组合作为一个更好的标准函数存在:
main = do
print $ myLast [1,2,3,4]
编译器从
putStrLn x
那x
一定是一个String
。推断的类型
myLast [1,2,3,4]
是Num a => a
,当你现在用你代替a
时,String
你得到
Num String => String
这一切都很合乎逻辑,只是类型检查器记住了Num
约束源自文字1
。
因此,您收到的消息只是表示数字不是字符串的另一种方式,而 putStrLn 非常想要一个字符串。或者,如果您愿意,如果只有字符串是数字,则表达式的类型会很好。
putStrLn
具有类型String -> IO ()
,因此您需要先将列表元素转换为字符串。
你可以这样做show
:
putStrLn $ show $ myLast [1,2,3,4]