首页 文章

使用Haskell 's “Maybe”, type declarations [beginner'的问题]

提问于
浏览
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) 失败时("Ambiguous type variable `a0' in the constraint: (Show a0) arising from a use of 'qqq'")

  • 当我想添加类型签名时如果失败:

  • qqq :: Maybe x => x -> IO () - > Type constructor 'Maybe' used as a class - >不是吗?

  • qqq :: (Maybe x) -> IO () . 现在签名本身看起来很成功 . 但 main = qqq (Just 43) 开始失败,如 main = qqq (Nothing) 案例那样神秘的 (Show a0) 错误 .

问题:

  • 为什么用 Nothing 调用qqq与使用 Just 43 调用有什么不同?

  • (Show a0) 是什么?它仅在错误消息中提及 . 任何使用它的尝试都会导致像"Show not in the scope"这样的东西 .

  • 这是什么类型的正确签名?如何推导Haskell打印类型签名?期待像:

f 0 = 2
f x = (f (x-1)) + 3

main = print get_type_as_string(f)
-- prints "Number -> Number"

1 回答

  • 9

    qqq 的类型是:

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

    这意味着 qqq 采用 Maybe a 类型的一个参数并返回没有值的IO操作,其约束为 a 实现 Show 类型类 . 要找出 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中的一行上,但含义相同) .

    当main调用 qqqqqq (Just 43) 时,很明显 Maybe a 的具体类型是数字类型(ghci默认为Integer),因此 qqq 具有 Maybe Integer -> IO () 的具体类型 . 但是,使用 qqq Nothinga 的主要调用 qqq 可以是任何内容(它是不明确的)并且ghci报告错误 .

相关问题