[英]Manually deriving the type of fun xss = \f -> let ope x y = x . f . y in foldr1 ope xss
我正在尝试手动得出fun xss = \\f -> let ope xy = x . f . y in foldr1 ope xss
的类型fun xss = \\f -> let ope xy = x . f . y in foldr1 ope xss
fun xss = \\f -> let ope xy = x . f . y in foldr1 ope xss
F 。 ÿ
y :: t1 -- First occurrence
f :: t2 -- First occurrence
(.) (b1 -> c1) -> (a1 -> b1) -> a1 -> c1 -- (.) definition
t1 ~ a1 -> b1 -- y unified with (a1 -> b1)
t2 ~ b1 -> c1 -- y unified with (b1 -> c1)
y :: a1 -> b1
f :: b1 -> c1
---
f . y :: a1 -> c1 -- Cancellation rule
\\ f->让ope xy = x。 F 。 ÿ
(.) (b2 -> c2) -> (a2 -> b2) -> a2 -> c2 -- (.) definition
x :: t3 -- First occurrence
t3 ~ b2 -> c2 -- x unified with (b2 -> c2)
a1 -> c1 ~ a2 -> b2 -- f . y unified with (a2 -> b2)
a1 ~ a2
c1 ~ b2
y :: a2 -> b1 -- Substituing a1 by a2
f :: b1 -> b2 -- Substituing c1 by b2
x :: b2 -> c2 -- Substituing t3 by b2 -> c2
---
x . f . y :: a2 -> c2 -- Cancellation rule
(\f -> let ope x y :: x . f . y)
:: (b2 -> c2) -> (a2 -> b1) -> (b1 -> b2) -> a2 -> c2 -- Adding f
foldr1 ope xss
foldr1 :: (a -> a -> a) -> [a] -> a -- foldr1 definition
xss ~ t4 -- First occurrence
然后a ~ (b2 -> c2), a ~ (a2 -> b1), a ~ (b1 -> b2) and t4 ~ [a]
似乎是错误的。
有什么帮助吗?
谢谢,
塞巴斯蒂安。
从功能开始
fun xss = \f -> let ope x y = x . f . y in foldr1 ope xss
我将其重写为
fun xss f = foldr1 ope xss
where ope x y = x . f . y
因此,我们从foldr1
开始:
foldr1 :: (a -> a -> a) -> [a] -> a
这样我们就可以分解
foldrl1
ope -- (a -> a -> a)
xss -- [a]
所以ope :: a -> a -> a
,这真的很有用,因为它将x
和y
的类型简化为完全限制为a
,或者换句话说,它们都具有相同的类型。 由于它们都是函数(按.
要求),因此不必长久地统一它们的类型,我只是说x, y :: b -> c
ope x y = x . f . y
-- (b -> c) . (s -> t) . (b -> c)
我现在将f
的类型保留为unknowns,除了指定它必须是一个函数之外。 因为我们知道x
和y
具有相同的类型,所以我们现在可以说y
的输出类型与f
的输入类型相同,因此s ~ c
,并且f
的输出类型必须与x
相同的输入类型,所以t ~ b
,所以我们得到
ope x y = x . f . y
-- (b -> c) . (c -> b) . (b -> c)
现在,我们可以填写fun
的签名了。 我们已经知道xss
的类型,它是foldr1
a ~ b -> c
,并且由于foldr1
的输出类型也是a
,我们得到
fun :: [b -> c] -> (c -> b) -> (b -> c)
实际上,这就是GHCi
给我们的类型
这是推导。
fun xss = \f -> let ope x y = x . f . y in foldr1 ope xss
fun xss f = foldr1 ope xss
where
ope x y = x . f . y y :: a -> b
= y >>> f >>> x f :: b -> c
a -> b b -> c c -> d x :: c -> d
:: a -------------------> d
ope x y :: a->d
ope :: (c->d) -> (a->b) -> (a->d)
foldr1 :: ( a1 -> a1 -> a1 ) -> [ a1 ] -> a1 c ~ a, d ~ b
((a->b) -> (a->b) -> (a->b)) -> [a->b] -> (a->b) a1 ~ a->b
foldr1 ope xss :: (a->b)
fun xss f :: a->b
fun :: [a->b] -> (b->a) -> (a->b)
函数组成是关联的: f . (g . h)
f . (g . h)
=〜= (f . g) . h
(f . g) . h
。 这就是为什么表达式f . g . h
f . g . h
f . g . h
格式正确。
就像(.) :: (b->c) -> (a->b) -> (a->c)
创建了一个由两个函数组成的链,两个函数相互馈送,即f . g . h
f . g . h
f . g . h
表达式创建一个由三个函数组成的链,每个函数都将其前任的输出作为输入。
有时使用(.)
的表亲>>>
会更容易,它只会翻转参数的顺序:
f . g === g >>> f
它在Control.Category
定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.