[英]Is there a way to implicitly coerce a type to another wrapper type in haskell?
[英]Does <- implicitly coerce types in a Haskell do block?
我的问题与另一个问题的答案有关: https : //stackoverflow.com/a/11766789/3212958
在他的回答中,ertes写下了以下类型的签名
select :: [a] -> [(a, [a])]
但是,当实际使用select
时,ertes会在do
块中写入以下内容
(y, ys) <- select xs
请帮助我阐明元组(y, ys)
匹配select的返回类型,即[(a, [a])]
。 Haskell在某些时候强迫这些类型吗? (Haskell是否强制类型?) <-
从select
返回的列表monad中提取类型(a, [a])
的元组?
谢谢,马克斯
---编辑:---
@Lee在尝试推理类型之前提醒newbs去desugar。 在制作>>=
显式后,更清楚的是发生了什么。 脱毒后,有问题的功能如下:
select xs >>= \(y, ys) -> fmap (y:) (perms (n - 1) ys)
对于列表, xs >>= f = concat (map f xs)
。 因此(y, ys)
在此上下文中更好地读取(y, ys)
作为映射列表的函数的签名。
在do
记号,
do x1 <- action1
action2
被翻译成action1 >>= \\x1 -> action2
这意味着如果action1
对某些monad m
具有类型ma
,则x1
具有类型a
。 它并不是真正强制类型,而是从monadic动作action1
“解包”该值并将其绑定到x1
。
(y, ys)
属于(b, c)
类型
select
的返回类型是[(a, [a])]
在<-
类型实际上是d
和Monad m => md
。 所以我们可以编写以下类型的等式:
(b, c) ~ d
[(a, [a])] ~ Monad m => m d
解决很容易。 首先将第一个等式中的d
替换为第二个等式:
[(a, [a])] ~ Monad m => m (b, c)
现在看看发生了什么,我将使用[]类型构造函数的前缀形式(它不是有效的haskell,但你应该得到这个想法):
[] (a, [a]) ~ Monad m => m ( b, c)
所以
m ~ []
(a, [a]) ~ (b, c)
此时,编译器检查instance Monad [a]
存在。 其余的很简单:
a ~ b
[a] ~ c
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.