haskell - Haskell 中 MonadPlus 的默认类型评估是什么?
问题描述
我有以下代码:
import Control.Monad
coin :: MonadPlus m => m Int
coin = return 0 `mplus` return 1
如果我对coin :: Maybe Int
解释器进行评估,它会优先级Just 0
。这是正常的,因为将 Maybe 实现为 MonadPlus 的实例。
如果我对解释器进行评估coin :: [Int]
,它会打印[0, 1]
,因为mplus
on list 的实现是append
.
coin
但是,如果我在没有任何类型装饰器的情况下评估0
. 为什么?解释器“转换”什么类型coin
来评估它?
此代码摘自:http ://homes.sice.indiana.edu/ccshan/rational/S0956796811000189a.pdf
解决方案
是的,这是 ghci 的一个没有很好记录的角落。当你在 ghci 中输入一个表达式时,它使用表达式的类型来决定做什么:
IO ()
: 运行动作,什么也不做。Show a => IO a
:运行动作和print
结果。- 任何其他
IO a
:运行动作,不做任何进一步的事情。 - 其他任何东西:用 . 包裹整个表达式
print
。
它如何决定一个事物具有这些类型中的哪一种?简单:它尝试统一上述每个签名的表达式类型,并解决所有产生的约束。(对于行家来说:这是对扩展默认规则的补充!这解释了为什么它似乎默认了m
,即使标准默认规则和扩展默认规则都没有说明要使用什么默认值。)
因此,由于您的表达式不与 统一,IO ()
但与 统一Show a => IO a
,ghci 在统一期间找到m ~ IO
(and a ~ Int
),发现有一个MonadPlus IO
(and a Show Int
) 实例来解决约束,运行您的操作并打印结果。
推荐阅读
- php - 无法正确获取和连接 oracle-20c 与 php html
- wix - WiX Toolset 将 ODBC-32 管理器快捷方式添加到开始菜单
- android - 由于静态引用 Android 中的内部类导致的内存泄漏
- python - 如何从源文件(.tgz)在 Ubuntu virtualenv 中安装 python 3.8
- python - 为什么双反斜杠在python字典中不起作用
- c# - 如何在 C# 中为 ExpandoObject 模拟 GetType().GetProperties() 和 PropertyInfo.GetValue()
- javascript - REACT - 如何将函数传递给 axios api 调用
- gcc - GCC:带有返回值的赋值块使宏更容易?
- php - SQLite SQLSTATE[HY000]:一般错误:8 次尝试写入只读数据库
- google-sheets-importxml - 如何使用 IMPORTXML 导出 img alt