繁体   English   中英

如何在Haskell中实现'show'?

[英]how is 'show' implemented in Haskell?

我试图了解类型系统在Haskell中的工作原理。

class (Show a) => MyShow a where 
    myShow :: a -> String

instance MyShow Integer where 
    myShow = show 

myshow :: (Show a) => a -> String
myshow = show

main  = do 
    putStrLn $ myshow 1
    putStrLn $ myShow (2 :: Integer) -- why do I need '::Integer' here?

为什么'myshow 1'在没有类型的情况下工作,而'myShow 2'在没有显式类型的情况下导致错误:

Ambiguous type variable `a0' in the constraints:
  (MyShow a0) arising from a use of `myShow'
              at nooverinst.hs:12:16-21
  (Num a0) arising from the literal `2' at nooverinst.hs:12:23
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely `myShow 2'
In the expression: putStrLn $ myShow 2
In the expression:
  do { putStrLn $ myshow 1;
       putStrLn $ myShow 2 }

同样奇怪的是,使用GHCI时没有错误:

*Main> myShow 2
"2"

那么,在这种情况下,'myshow'和'myShow'有什么区别? 它们都被定义为与'show'相同。 我错过了什么?

更新:

答案摘要:此行为与默认有关。 'show 1'和'myshow 1'工作的事实是一个特例(参见关于默认的Haskell报告部分 )。 在源代码之上添加'default()'会关闭默认值并导致代码在'myshow 1'处中断,因为类型歧义不再通过默认来解决。 所以,实际上,两个putStrLn行都应该在最后有类型签名。

感谢所有回答的人!

这与默认(Haskell标准的一个较暗角落)有关,如http://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-790004.3.4所述

简而言之,Haskell以特殊方式处理数值类,并且默认自动产生数值类的歧义,但当涉及的其他约束是基类时。 从这个意义上说, Show也很特别,你自己定义的MyShow以不同的方式处理。

在GHCi中,扩展的默认规则启动,这略微放宽了限制。 这些描述见http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluation.html#extended-default-rules

由于1可以具有任何Num类型,因此编译器必须使用某种方法来选择某种类型。 这是由违约处理的。 但默认只发生在Prelude课程而不是你的课程。 查看有关Haskell报告中的默认值的部分,并将其全部拼写出来。

有几种数字类型( Num实例),Haskell在你写2时不知道你的意思。 通常你可以逃脱它,因为ghc / ghci被编程为像2+2这样的表达式选择像Integer这样的默认类型。 你在myshowmyshow因为Haskell正在使用与自动选择的Num实例绑定的Show实例,但不是在myShow

你自己的类型类MyShowNum没有任何关系,所以Haskell不能使用默认规则为你选择。 [抱歉,我的上一版本错误地解决了这个问题。]

这仅仅是数字文字像一个古怪36.7等,因为它们是重载(可以代表一个以上类型的数据),这样你就不会遇到这个问题与其他类型如Char等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM