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

时间:2011-07-16 08:43:14

标签: 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)

可是:

  • 当我尝试使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. 为什么使用Nothing拨打qqq与使用Just 43拨打电话有什么不同?
  2. 什么是(Show a0)?它仅在错误消息中提及。任何使用它的尝试都会导致类似“显示不在范围内”的内容。
  3. 这是什么类型的正确签名?如何推导Haskell打印类型签名?期待像:
  4. f 0 = 2
    f x = (f (x-1)) + 3
    
    main = print get_type_as_string(f)
    -- prints "Number -> Number"
    

1 个答案:

答案 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 ()。但是,使用qqqqqq Nothing的主要调用a可以是任何内容(它不明确),ghci会报告错误。