haskell - Haskell中的美元符号($)和id函数之间有关系吗?

标签 haskell

其中一天,我正在阅读 Monad Challenge 上的评论。 (我强烈推荐给 Haskell 的任何初学者,比如我自己),我最终选择了 this thread我在哪里读到 ($) = id .

I don't know about scaring people, but many programming languages have concepts that are best demonstrated with small examples that make people say "whoa".

For example, it's amazing that append() in Prolog can be run "backwards" from the concatenated result to yield all the lists that can be concatenated to produce it. Or that the monadic bind operator in Haskell (>>=) can be defined in terms of join and fmap, or that ($) = id.



($) = id !?
< 在 Raskell/Ghci 中试用 >

我现在明白为什么这是真的了,但仍然......哇!感谢那! (...)

然后我检查了 base -4.10.0.0代码,查找 ($) 的定义和 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!

And their implementations are:

-- | Identity function.
id                      :: a -> a
id x                    =  x

-- | Application operator.
{-# INLINE ($) #-}
($)                     :: (a -> b) -> a -> b
f $ x                   =  f x

我尝试在 GHCi 上一个一个地交换,我得到的只是类型错误(如我所料)。现在,我有比我开始时更多的问题:
  • 他们说 ($) = id 是什么意思?
  • 在哪些情况下这种说法是正确的?这是否意味着我可以使用一个而不是另一个?
  • base ,这句话是什么意思($)是“有点神奇(它可以返回未提升的类型)”和“被连接”吗?
  • 而“不同场景下的不同类型”呢?我认为由于 Haskell 是一种强类型语言,一旦定义了类型签名,该签名就会保留到 Time 结束。这不是真的吗?是否存在可以更改函数类型的情况?
  • 最佳答案

    Haskell 确实是强类型的。该问题与 ($) 的某些黑客行为有关。运算符(operator)。不幸的是,我不知道它是关于什么的:希望有人会回答你的问题 3(和问题 4 自动)。

    关于问题1,看类型:

    id :: a -> a
    ($) :: (a -> b) -> (a -> b)
    

    重命名 c = a -> b你会得到 ($) :: c -> c ,这意味着 ($) 的类型是 id 类型的规范,因此至少类型允许我们使用 id实现($) .

    现在,看看 ($) 的定义:
    f $ x = f x
    

    让我们稍微重写一下:
    ($) f = \x -> f x
    

    并应用 eta-reduction:
    ($) f = f
    

    现在可以清楚地看到($)只是 id使用更具体的类型(因此 f 始终是一个函数)。

    请注意,它不能以另一种方式工作,因为 ($) 的类型更具限制性。例如,您可以调用id 5并获取 5结果,但是 ($) 5不会进行类型检查:5没有 a -> b 形式的类型.
    ($)的点是它具有非常低的优先级,并且允许避免在 f 的参数周围使用大括号,并且可以像这样使用
    someFunction $ whatever complex computation you dont need braces around
    

    关于haskell - Haskell中的美元符号($)和id函数之间有关系吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47317555/

    相关文章:

    haskell - Yesod数据库持久记录访问

    haskell - Hindley-Milner 中的 `Let` 推理

    Haskell长度+ map 解释?

    haskell - Happstack中间件缺乏?

    haskell - 为什么foldr 立即返回?

    haskell - 如何对 `Constraint` 类型的变量施加约束?

    haskell - 理解 HList 的这个定义

    haskell - 使用 Netwire 从值生成列表

    haskell - 为什么我的 "apply"标签在 Heist 0.11.0.1 中不再有效?

    variables - 如何在 Haskell 中分割线?