6

我已经开始尝试使用 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. 为什么用 qqqNothing调用与用 调用如此不同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"
4

1 回答 1

9

的类型qqq是:

qqq :: Show a => Maybe a -> IO ()

这意味着qqq接受一个类型参数Maybe a并返回一个没有值的 IO 操作,并带有实现类型类的约束。要找出是什么,您可以在 ghci 中使用。aShowShow:i Show

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 中的一行,但含义是相同的)。

当 main 调用qqqqqq (Just 43),很明显 的具体类型Maybe a是数字类型(ghci 默认为整数),qqq具体类型也是Maybe Integer -> IO ()qqq但是,带有qqq Nothing,的主要调用a可以是任何东西(它是模棱两可的)并且 ghci 报告错误。

于 2011-07-16T09:00:46.307 回答