Haskell Prelude中'const'的重点是什么?

stu*_*ith 87 haskell

通过Haskell Prelude,我看到了一个函数 const:

const x _ = x
Run Code Online (Sandbox Code Playgroud)

我似乎无法找到有关此功能的任何相关内容.

重点是什么?任何人都可以举例说明这个函数的用途吗?

ham*_*mar 82

当您不需要所有灵活性时,它可用于传递到高阶函数.例如,monadic序列运算符>>可以根据monadic绑定运算符来定义

x >> y = x >>= const y
Run Code Online (Sandbox Code Playgroud)

它比使用lambda有点整洁

x >> y = x >>= \_ -> y
Run Code Online (Sandbox Code Playgroud)

你甚至可以无点使用它

(>>) = (. const) . (>>=)
Run Code Online (Sandbox Code Playgroud)

虽然在这种情况下我并不特别推荐.

  • 啊,所以它更像是一个'函数生成器' - 我用一个参数,它给了我一个函数(带一个参数),它总是返回一个常量值.所以`map(const 42)[1..5]`导致`[42,42,42,42,42]`. (45认同)
  • +1.使用解析器组合器时,它也经常出现. (8认同)
  • @stusmith:你可以用一些有趣的方式使用它:`head = foldr const(错误"Prelude.head:empty list")` (8认同)
  • stusmith:你明白了.`const`对于应用于单个参数以产生需要一个函数的函数(例如传递给`map`)非常有用. (2认同)

jbe*_*man 27

要添加到哈马尔的优良直接的答案:像卑微的功能constid如出于同样的原因,他们是一个高阶函数真正有用的根本SKI组合子演算.

并不是说我认为haskell的前奏函数是在正式系统之后有意识地建模的.只是在haskell中创建丰富的抽象非常容易,所以你经常会看到这些类型的理论事物在实际上很有用.

无耻的插头,但我的博客上讲述了应用型实例如何(->)实际上是SK组合子在这里,如果这是你到之类的话.

  • 嗯,SKI组合器肯定影响了Prelude.我记得和Joe Fasel争论是否应该包括S组合子. (8认同)
  • 顺便说一下,`(( - >)e)`也是读者monad - 用`Reader`之类的东西只是`newtype`包装器 - 而`ask`函数则是`id`,所以就是`` `combinator也是.如果你看看Haskell Curry的原始BCKW基础,`B`,`K`和`W`分别是`fmap`,`return`和`join`. (4认同)

Lan*_*dei 22

一个简单的使用示例constData.Functor.(<$).有了这个功能,你可以说:我这里有一个带有无聊内容的仿函数,但我希望在其中有其他有趣的东西,而不改变仿函数的形状.例如

import Data.Functor

42 <$ Just "boring"
--> Just 42

42 <$ Nothing
--> Nothing

"cool" <$ ["nonsense","stupid","uninteresting"]
--> ["cool","cool","cool"]
Run Code Online (Sandbox Code Playgroud)

定义是:

(<$) :: a -> f b -> f a
(<$) =  fmap . const
Run Code Online (Sandbox Code Playgroud)

或者写得没有意义:

cool <$ uncool =  fmap (const cool) uncool
Run Code Online (Sandbox Code Playgroud)

你看到const这里如何用来"忘记"输入.


jub*_*0bs 19

我似乎无法找到有关此功能的任何相关内容.

许多其他答案讨论相对深奥(至少对新人)的应用const.这是一个简单的问题:你可以const用来摆脱一个带有两个参数的lambda,扔掉第一个参数,但用第二个抛出一些有趣的东西.

例如,以下(效率低下!)的实现length,

length' = foldr (\_ acc -> 1 + acc) 0
Run Code Online (Sandbox Code Playgroud)

可以改写为

length' = foldr (const (1+)) 0
Run Code Online (Sandbox Code Playgroud)

这可能更优雅.

表达式const (1+)确实在语义上等同于\_ acc -> 1 + acc,因为它接受一个参数,将其抛弃,并返回该部分(1+).

  • 我花了5分钟才明白这是如何工作的:) (4认同)

Jon*_*ård 15

另一个用途是实现具有伪参数的类成员函数,该伪参数不应被评估(用于解析模糊类型).可以在Data.bits中的示例:

instance Bits Int where
  isSigned = const True
  bitSize  = const wordSize
  ...
Run Code Online (Sandbox Code Playgroud)

通过使用const,我们明确地说我们正在定义常量值.

我个人不喜欢使用伪参数,但如果在类中使用它们,那么这是一种编写实例的相当不错的方法.