Haskell GHCi中的“:t”和let表达式之间有什么区别

Haskell GHCi中的“:t”和let表达式之间有什么区别,haskell,Haskell,我想制作一个玩具函数,生成一个可能是一个,然后提升show,使其成为一个可能是字符串,但结果对我来说很奇怪: λ> :t liftM show . Just liftM show . Just :: Show a1 => a1 -> Maybe String λ> liftM show . Just $ 10 Just "10" λ> let f = liftM show . Just λ> f 10 <interactive>:9:3:

我想制作一个玩具函数,生成一个
可能是一个
,然后提升
show
,使其成为一个
可能是字符串
,但结果对我来说很奇怪:

λ> :t liftM show . Just
liftM show . Just :: Show a1 => a1 -> Maybe String
λ> liftM show . Just $ 10
Just "10"
λ> let f = liftM show . Just
λ> f 10

<interactive>:9:3:
    No instance for (Num ()) arising from the literal `10'
    Possible fix: add an instance declaration for (Num ())
    In the first argument of `f', namely `10'
    In the expression: f 10
    In an equation for `it': it = f 10
λ> :t f
f :: () -> Maybe String
λ> let g = liftM show . Just :: (Show a) => a -> Maybe String
λ> :t g
g :: () -> Maybe String
λ> let h = liftM show . Just :: Int -> Maybe String
λ> :t h
h :: Int -> Maybe String
λ>:t liftM显示。只是
liftM展会。只是::Show a1=>a1->Maybe String
λ> liftM展会。只要10美元
只有“10”
λ> 让f=liftM显示。只是
λ> F10
:9:3:
没有由文字“10”生成的(Num())实例
可能的修复方法:为(Num())添加实例声明
在'f'的第一个参数中,即'10'
在表达式中:f10
在‘it’的方程式中:it=f10
λ> :t f
f::()->可能是字符串
λ> 让g=liftM显示。Just::(Show a)=>a->Maybe String
λ> :t g
g::()->可能是字符串
λ> 让h=liftM显示。只是::Int->可能是字符串
λ> :t h
h::Int->可能是字符串
我猜这与类型推断有关,但我真的不知道发生了什么:

  • 那神秘的
    ()
    是从哪里来的
  • 为什么GHCi没有抱怨含糊不清
Dum duum

下一个受害者

发生的情况是:对于一个看起来像“常量变量”(在其他语言也可能使用的意义上,即不是函数类型)的定义,例如
f=…
,假设您希望它实际表现为一个常量(,确切地说)。这意味着,它不能是多态的,因为对于参数多态性,函数基本上有一个额外的隐式参数(类型
a1
应该是的信息)

为了达到这一实际常数,ghci将此类型变量转换为它认为最不合适的任何特定类型。这里,唯一的限制是
Show
;最简单的类型是
()

解决这个问题的“正确”方法是关闭单态限制:

前奏曲>:集合-XnomonomogomismRestriction
序曲>:m+控制。单子
前奏曲控制。单子>让f=liftM显示。只是
前奏曲控制。单子>F10
只有“10”

或者,您可以像在实际源文件中一样,为ghci中的标识符提供适当的签名:

序曲控件.Monad>让g::Show a=>a->Maybe String;g=liftM显示。只是
前奏曲控制。单子>G10
只有“10”

仅在
=
的RHS上执行此操作不起作用,因为单态限制只有在解决后才会生效,并默认删除变量(除非像在
h
中一样,因为您向RHS提供了单态签名,所以首先没有变量)

还有一件事你可以做,简单地给函数一个显式的参数,那么单态限制根本不适用。也就是说,非点自由书写:

序曲控制.Monad>让i a=liftM显示$Just a
前奏曲控制.单子>i10
只有“10”


如果我在我的
.ghci
中放入
nomonomogomphismrestriction
,它可能会造成任何损坏吗?不太可能。现实中最糟糕的情况是,有些事情会变得更慢,因为不再共享多态常量,但不太可能成为问题。