使用Haskell的"Maybe",输入声明[beginner's question]

Vi.*_*Vi. 6 haskell nothing maybe type-signature

我已经开始尝试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)
Run Code Online (Sandbox Code Playgroud)

但:

  • 当我试图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).

问题:

  1. 为什么调用qqq与调用Nothing是如此不同Just 43
  2. 什么是(Show a0)?它仅在错误消息中提及.任何使用它的尝试都会导致类似"显示不在范围内"的内容.
  3. 什么是正确的类型签名?如何推导Haskell打印类型签名?期待像:
f 0 = 2
f x = (f (x-1)) + 3

main = print get_type_as_string(f)
-- prints "Number -> Number"
Run Code Online (Sandbox Code Playgroud)

Ant*_*tti 9

类型qqq是:

qqq :: Show a => Maybe a -> IO ()
Run Code Online (Sandbox Code Playgroud)

这意味着,qqq采用类型的一个参数Maybe a和没有值返回一个IO动作,与约束a实现Show类型类.要了解它是什么Show,您可以:i Show在ghci中使用.

Show是一个类型类,它要求可以将类型的值转换为字符串.qqq有约束因为print想要打印出值(print有类型Show a => a -> IO ()).Maybe不是类型类,而是数据类型.您可以在此处阅读有关类型类的更多信息.

您可以让GHC通过在.hs文件中键入函数,然后使用ghci(ghci Myfile.hs)加载文件,然后键入:t qqq以显示类型来推断类型签名.您还可以在交互式会话中定义函数let qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x }(它看起来有点不同,因为函数定义必须在ghci中的一行上,但含义相同).

当主调用qqqqqq (Just 43),很明显具体类型Maybe a是数字类型(ghci默认为Integer),qqq具体类型为Maybe Integer -> IO ().然而,主通话qqq使用qqq Nothing,a可以是任何东西(它是含糊不清)和ghci的报告错误.

  • 请注意,您不必根据`case`重写qqq以使其在ghci中工作.你需要的只是在开头添加一个`let`并用`;`代替换行符:`let qqq Nothing = print"..."; qqq(Just x)= print"...">> print x` (3认同)