这几天我正在读一篇评论莫纳德挑战 http://mightybyte.github.io/monad-challenges/(我强烈推荐给像我这样的 Haskell 初学者),我最终得到了这个线程 https://news.ycombinator.com/item?id=10935313我在哪里读到的($) = id
.
我不知道这会吓到人们,但许多编程语言都有一些概念,这些概念最好通过小例子来展示,让人们说“哇”。
例如,令人惊奇的是,Prolog 中的append() 可以从连接的结果“向后”运行,以生成可以连接以生成它的所有列表。或者 Haskell 中的一元绑定运算符 (>>=) 可以根据 join 和 fmap 定义,或者 ($) = id。
($) = id !?
我现在明白为什么这是真的了,但仍然......哇啊!!感谢那! (...)
然后我检查了base-4.10.0.0 https://hackage.haskell.org/package/base-4.10.0.0/docs/src/GHC.Base.html代码,寻找定义($)
and id
,但在顶部我读到了这个:
NOTA BENE: Do NOT use ($) anywhere in this module! The type of ($) is
slightly magical (it can return unlifted types), and it is wired in.
But, it is also *defined* in this module, with a non-magical type.
GHC gets terribly confused (and *hangs*) if you try to use ($) in this
module, because it has different types in different scenarios.
This is not a problem in general, because the type ($), being wired in, is not
written out to the interface file, so importing files don't get confused.
The problem is only if ($) is used here. So don't!
他们的实现是:
-- | Identity function.
id :: a -> a
id x = x
-- | Application operator.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x
我尝试在 GHCi 上交换一个,但得到的只是类型错误(正如我预期的那样)。现在,我有比一开始更多的问题:
- 他们这么说是什么意思
($) = id
?
- 在哪些情况下该陈述是正确的?这是否意味着我可以使用其中之一来代替另一个?
- In the
base
,这句话是什么意思($)
是“有点神奇(它可以返回未提升的类型)”和“被连接”?
- 那么“不同场景不同类型”呢?我认为,由于 Haskell 是一种强类型语言,一旦定义了类型签名,该签名就会保留到时间结束。这不是真的吗?是否存在可以更改函数类型的情况?
Haskell 确实是强类型的;该问题与特定于某些黑客行为有关($)
操作员。不幸的是,我不知道它是关于什么的:希望有人会自动回答你的问题 3(和问题 4)。
关于问题1,看一下类型:
id :: a -> a
($) :: (a -> b) -> (a -> b)
Rename c = a -> b
你得到($) :: c -> c
,这意味着类型($)
是类型的规范id
,这样至少类型允许我们使用id
实施($)
.
现在,看看定义($)
:
f $ x = f x
让我们重写一下:
($) f = \x -> f x
并应用 eta 缩减:
($) f = f
现在可以清楚地看到($)
只是id
具有更具体的类型(这样f
始终是一个函数)。
请注意,它不能以其他方式工作,因为($)
更具限制性。例如,您可以调用id 5
并得到5
结果,但是($) 5
不会进行类型检查:5
没有表单的类型a -> b
.
要点是($)
是它的优先级非常低,并且允许避免在参数周围使用大括号f
,并且可以像这样使用
someFunction $ whatever complex computation you dont need braces around
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)