类型“Show a => Maybe a - > IO()”是什么意思?

时间:2015-06-17 10:12:01

标签: haskell types

我有一个代码片段,如下所示

displayAge :: Show a => Maybe a -> IO ()
displayAge maybeAge =
  case maybeAge of
    Nothing -> putStrLn "Invalid year"
    Just maybeAge -> putStrLn $ show maybeAge

此函数从控制台获取其参数,并通过readMay函数传递给它,如下所示;

main = do
  putStrLn "Your birth year"
  strYear <- getLine
  let maybeAge = do
        intYear <- readMay strYear
        return (processYear intYear)
  displayAge maybeAge

请解释一下displayAge函数的类型声明。为什么使用Show a

2 个答案:

答案 0 :(得分:5)

displayAgeMaybea的值,其中a是任何类型Show n。

首先阅读Haskell签名中=>右侧的内容(即Maybe a -> IO ()

)通常很有用

答案 1 :(得分:0)

所以,这是一个类型声明,所以它会告诉你需要提供给函数displayAge的内容,以便类型检查器满意。后面的行实际上描述了函数的工作原理。类型声明(几乎总是)是可选的,但它们是重要的文档,并且经常使错误消息更有意义,因为编译器现在知道你想要做什么,并且可以将它与你实际做的相比较。

Show a

声明的第一部分,=>之前的部分告诉了我们a的一些内容。我们注意到a是小写的,因此不是类型而是类型变量。实际使用displayAge函数时,您可以使用任何类型代替a(Int,String,[Double]等...)但这表示必须有{{} 1}}该类型的实例。所以几乎任何不是函数的类型。如果haskell中的类仍然让您感到困惑,请查看this sectionLearn You a Haskell for Great Good(实际上它与_Why关于Ruby的教程一样好)

Show

有许多方法可以读取Haskell类型的签名,但如果是新的,它可以帮助在最后一个箭头(Maybe a)之前考虑所有类型作为&#34;输入&#34;最后的类型为&#34;输出。&#34;这个想法错过了currying和一流的功能,但它确实可以帮助你开始。

因此,此功能需要->,并会为您提供Maybe a

那么IO()是什么?如果您不熟悉Maybe a类型,您当然应该努力成为这样的类型。这是二阶类型。这意味着,为了使用它,你需要给它一些其他类型来包含。也许拥有其他类型。因此Maybe成立并Maybe IntInt成立Maybe String。但是这个函数被设计为使用String来保存任何类型(这么长时间它有一个像我们上面提到的Show实例)。再次注意小写Maybe如果此函数特别需要某种类型,它将使用以大写字母开头的类型。

a

好的,这可能是困难的部分。这个功能而不是计算一些新的价值,对现实世界做了一些事情 - 所有存在于haskell世界之外的东西都是现实世界。因此,用户输入和输出,网络内容和可变内存都必须进入IO类型。 (是的,它是二阶就像Maybe)这是着名的,可爱的IO monad,我们希望你听说过,并会学会爱。当函数附带类型IO()时,表示执行某事而不是返回值。在我们的例子中,我们认为它应该显示和年龄,对吗?您需要在IO()块中使用displayAge,例如do函数*。

*不严格来说,你可以使用bind(main)代替,但是这显然是一个初学者的问题,我们有关于不编写monad教程的规则,对吗?