我已经开始尝试使用Haskell并遇到问题。 qqq是一个函数,如果使用“Nothing”调用则应打印一个字符串,如果使用“Just something”调用则打印其他内容。
第一次尝试似乎有效:
qqq Nothing = print "There isn't anything to be printed."
qqq (Just x) = print "There is something to be printed." >> print x
main :: IO ()
main = qqq (Just 43)
可是:
main = qqq (Nothing)
失败时(约束中的“模糊类型变量`a0':(显示a0)因使用'qqq'而产生”)qqq :: Maybe x => x -> IO ()
- > Type constructor 'Maybe' used as a class
- >但不是吗?qqq :: (Maybe x) -> IO ()
。现在签名本身看起来很成功。但main = qqq (Just 43)
开始因(Show a0)
案例中出现的神秘main = qqq (Nothing)
错误而失败。问题:
Nothing
拨打qqq与使用Just 43
拨打电话有什么不同?(Show a0)
?它仅在错误消息中提及。任何使用它的尝试都会导致类似“显示不在范围内”的内容。f 0 = 2
f x = (f (x-1)) + 3
main = print get_type_as_string(f)
-- prints "Number -> Number"
答案 0 :(得分:9)
qqq
的类型是:
qqq :: Show a => Maybe a -> IO ()
这意味着qqq
接受Maybe a
类型的一个参数并返回没有值的IO操作,约束 a
实现Show
1}}类型类。要了解Show
是什么,您可以在ghci中使用:i Show
。
Show
是一个类型类,它要求将类型的值转换为字符串。 qqq
具有约束条件,因为print
想要打印出值print
具有类型Show a => a -> IO ()
)。 Maybe
不是类型类,而是数据类型。您可以阅读有关类型here的更多信息。
您可以让GHC通过在.hs文件中键入函数,然后使用ghci(ghci Myfile.hs
)加载文件,然后键入:t qqq
来显示类型来推断类型签名。您还可以使用let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x }
在交互式会话中定义函数(它看起来有点不同,因为函数定义必须在ghci中的一行上,但含义相同)。
当使用qqq
主调用qqq (Just 43)
时,很明显Maybe a
的具体类型是数字类型(ghci默认为Integer),因此qqq
具体类型Maybe Integer -> IO ()
。但是,使用qqq
,qqq Nothing
的主要调用a
可以是任何内容(它不明确),ghci会报告错误。