gpt4 book ai didi

haskell - 组合函数组合 : How does (. ).(.) 有效吗?

转载 作者:行者123 更新时间:2023-12-03 10:32:27 25 4
gpt4 key购买 nike

(.)采用两个函数,它们采用 一个 值并返回一个值:

(.) :: (b -> c) -> (a -> b) -> a -> c

由于 (.)需要 两个 论据,我觉得 (.).(.)应该是无效的,但它很好:
(.).(.) :: (b -> c) -> (a -> a1 -> b) -> a -> a1 -> c

这里发生了什么?我意识到这个问题的措辞很糟糕......由于currying,所有函数实际上只需要一个参数。也许更好的说法是类型不匹配。

最佳答案

让我们首先为机械证明玩 typechecker。之后我将描述一种直观的思考方式。

我要申请(.)(.)然后我会申请(.)到结果。第一个应用程序帮助我们定义变量的一些等价性。

((.) :: (b -> c) -> (a -> b) -> a -> c) 
((.) :: (b' -> c') -> (a' -> b') -> a' -> c')
((.) :: (b'' -> c'') -> (a'' -> b'') -> a'' -> c'')

let b = (b' -> c')
c = (a' -> b') -> a' -> c'

((.) (.) :: (a -> b) -> a -> c)
((.) :: (b'' -> c'') -> (a'' -> b'') -> a'' -> c'')

然后我们开始第二个,但很快就卡住了......
let a = (b'' -> c'')

这是关键:我们想要 let b = (a'' -> b'') -> a'' -> c'' , 但我们已经定义了 b ,因此我们必须尝试统一 --- 尽可能匹配我们的两个定义。幸运的是,他们确实匹配
UNIFY b = (b' -> c') =:= (a'' -> b'') -> a'' -> c''
which implies
b' = a'' -> b''
c' = a'' -> c''

有了这些定义/统一,我们可以继续申请
((.) (.) (.) :: (b'' -> c'') -> (a' -> b') -> (a' -> c'))

然后展开
((.) (.) (.) :: (b'' -> c'') -> (a' -> a'' -> b'') -> (a' -> a'' -> c''))

并清理它
substitute b'' -> b
c'' -> c
a' -> a
a'' -> a1

(.).(.) :: (b -> c) -> (a -> a1 -> b) -> (a -> a1 -> c)

老实说,这有点违反直觉。

这是直觉。先来看看 fmap
fmap :: (a -> b) -> (f a -> f b)

它将函数“提升”为 Functor .我们可以反复应用
fmap.fmap.fmap :: (Functor f, Functor g, Functor h) 
=> (a -> b) -> (f (g (h a)) -> f (g (h b)))

允许我们将函数提升到 Functors 的越来越深的层中.

原来数据类型 (r ->)Functor .
instance Functor ((->) r) where
fmap = (.)

这应该看起来很熟悉。这意味着 fmap.fmap转换为 (.).(.) .因此, (.).(.)只是让我们变换 (r ->)的更深层次的参数类型 Functor . (r ->) Functor实际上是 Reader Monad ,如此分层 Reader s 就像拥有多种独立的全局、不可变状态。

或者像有多个不受 fmap 影响的输入参数。 ing。有点像在(> 1)arity函数的“只是结果”上编写一个新的延续函数。

最后值得注意的是,如果您认为这些东西很有趣,它构成了 deriving the Lenses in Control.Lens 背后的核心直觉。 .

关于haskell - 组合函数组合 : How does (. ).(.) 有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17585649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com