Haskell GHCi如何选择Monad类型类的实例用于多态操作?

Haskell GHCi如何选择Monad类型类的实例用于多态操作?,haskell,ghci,Haskell,Ghci,我是哈斯凯尔的新手,所以这可能是一个noob问题 当我执行return 10>=returnGHCi显示10。当我用:t检查return 10的类型时,它只会说return 10::(Monad m,Num a)=>ma,而对于我的return 10的类型,我得到一个错误 但据我所知,Haskell一定使用了一个特定的>=实例来评估return 10>=return,那么它使用了哪个实例,以及它是如何决定使用哪个实例的呢?这遵循了GHCi有点像IO的巨大块的想法。每当您键入某个表达式时,它首先尝

我是哈斯凯尔的新手,所以这可能是一个noob问题

当我执行
return 10>=return
GHCi显示
10
。当我用
:t
检查
return 10
的类型时,它只会说
return 10::(Monad m,Num a)=>ma
,而对于我的
return 10的类型,我得到一个错误


但据我所知,Haskell一定使用了一个特定的
>=
实例来评估
return 10>=return
,那么它使用了哪个实例,以及它是如何决定使用哪个实例的呢?

这遵循了GHCi有点像
IO
的巨大
块的想法。每当您键入某个表达式时,它首先尝试查看结果的类型是否可以专用于
ioa
形式的内容。如果可以,它将执行
IO
操作并仅打印结果。只有在其他情况下,它才会打印表达式本身的结果

要强制GHCi转到您想要的任何特定monad,可以添加类型注释。请注意,
IO
的处理方式是如何不同的(与表达式在没有任何注释的情况下的处理方式相同)



另一方面,关于选择
Num
的哪个实例,存在一个完全不同的问题,这个问题与默认规则和单态限制有关。

我暂时将其作为“”的副本关闭。这个问题涉及如何为
a
选择
Num
实例,但我认为没有涉及如何为
m
选择
Monad
实例。所以我认为这不是一个完全重复的问题,应该得到一个仔细的回答。实际上,我想问的是,如何选择monad的一个特定实例作为泛型monad。我猜它使用了list的
>=
,但我不知道为什么。我怀疑它可能是IO单子。通常,ghci会尝试打印REPL结果,但如果遇到IO操作,则会执行该操作并打印该操作返回的结果。像
(Monad m,Num A)=>ma
这样的类型与
IO A
兼容,也许这就是它用来决定是否执行或打印当前REPL表达式的标准。我认为这与单态限制无关,而是用于默认()如果使用io monad作为repl,那么使用除monad之外的任何使用typeclass的不明确表达式都会给我一个错误,而不是选择一个默认值?@Juan,例如,如果我在
ghci
中键入
return mempty,我会得到一个不明确的类型错误,因此如果我正确理解了你的问题,然后是的。但是
mempty
(不带
返回
)可以工作并且默认为
()
type@Juan不有关ghci中使用的扩展违约规则的详细信息,请参见问题I。如果它不明确,不使用
Monad
,并且这些规则不适用,那么您应该得到一个错误。@Fabian签出并搜索
-XExtendedDefaultRules
。注意第三点“单元类型()添加到执行类型默认时尝试的标准类型列表的开头”,以及我们有一个
Monoid
实例用于
IO
()
ghci> return 10 >>= return :: Maybe Int
Just 10
ghci> return 10 >>= return :: [Int]
[10]
ghci> return 10 >>= return :: IO Int
10