В чем смысл "const" в прелюдии Хаскелла?


просматривая прелюдию Хаскелла, я см. функцияconst:

const x _ = x

Я не могу найти ничего подходящего для этой функции.

какой в этом смысл? Может ли кто - нибудь привести пример того, где эта функция может быть использована?

7 76

7 ответов:

это полезно для перехода к функциям более высокого порядка, когда вам не нужна вся их гибкость. Например, оператор монадической последовательности >> можно определить в терминах оператора монадической привязки как

x >> y = x >>= const y

это несколько аккуратнее, чем с помощью лямбда

x >> y = x >>= \_ -> y

и вы даже можете использовать его без точки

(>>) = (. const) . (>>=)

хотя я не особенно рекомендую это в данном случае.

чтобы добавить к отличному прямому ответу хаммара: скромные функции, такие как const и id действительно полезны в качестве функции более высокого порядка по той же причине, что они фундаментальной на Лыжное комбинаторное исчисление.

Я не думаю, что функции прелюдии Хаскелла были сознательно смоделированы после этой формальной системы или чего-то еще. Просто создание богатых абстракций в haskell очень легко, поэтому вы часто видите эти типы теоретических вещей появляются как практически полезные.

бесстыдный плагин, но я написал в блоге о том, как прикладной экземпляр для (->) на самом деле S и K комбинаторы здесь, если это то, чем ты занимаешься.

простой пример использования const - это Data.Functor.(<$). С помощью этой функции вы можете сказать: у меня есть здесь функтор с чем-то скучным в нем, но вместо этого я хочу иметь в нем эту другую интересную вещь, не меняя форму функтора. Е. Г.

import Data.Functor

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

42 <$ Nothing
--> Nothing

"cool" <$ ["nonsense","stupid","uninteresting"]
--> ["cool","cool","cool"]

определение:

(<$) :: a -> f b -> f a
(<$) =  fmap . const

или написано не так как бессмысленно:

cool <$ uncool =  fmap (const cool) uncool

вы видите, как const используется здесь, чтобы" забыть " о входе.

другое использование заключается в реализации функций-членов класса, которые имеют фиктивный аргумент, который не должен оцениваться (используется для разрешения неоднозначных типов). Пример, который может быть в данных.бит:

instance Bits Int where
  isSigned = const True
  bitSize  = const wordSize
  ...

используя const, мы явно говорим, что определяем постоянные значения.

лично мне не нравится использование параметров манекена, но если они используются в классе, то это довольно хороший способ написания экземпляров.

Я не могу найти ничего подходящего для этой функции.

многие из других ответов обсуждают относительно эзотерические (по крайней мере, для новичка) приложения const. Вот один простой: вы можете использовать const чтобы избавиться от лямбды, которая принимает два аргумента, выбрасывает первый, но делает что-то интересное со вторым.

например, следующее (неэффективно!) осуществление length,

length' = foldr (\_ acc -> 1 + acc) 0

можно переписать в виде

length' = foldr (const (1+)) 0

что, пожалуй, более элегантно.

выражение const (1+) действительно эквивалентно \_ acc -> 1 + acc, потому что он берет один аргумент, выбрасывает его и возвращает раздел (1+).

const может быть только выполнение вы ищете в сочетании с другими функциями. Вот пример, который я обнаружил.

((a,b),(c,d)) ⇒ (a,(c,(5,a)))

я могу дать прямое определение с сопоставлением шаблонов:

f ((a,b),(c,d)) = (a,(c,(5,a)))

Что делать, если я хочу бессмысленное (молчаливое) решение для такого рода переписывания? Некоторые мысли и возня позже, ответ заключается в том, что мы можем выразить любые переписывает с (&&&), const, (.), fst, snd. Обратите внимание, что (&&&) С Control.Arrow.

решение примера с использованием этих функций:

(fst.fst &&& (fst.snd &&& (const 5 &&& fst.fst)))

обратите внимание на сходство с (a,(c,(5,a))). Что делать, если мы заменим &&& С ,? Затем он читает:

(fst.fst, (fst.snd, (const 5, fst.fst)))

обратите внимание, как a является первым элементом первого элемента, и это то, что fst.fst проектов. Обратите внимание, как c является первым элементом второго элемента, и что это что fst.snd проектов. То есть переменные становятся путем к их источнику.

const позволяет ввести константы. Интересно, как имя совпадает со смыслом!

затем я обобщил эту идею с помощью Applicative, чтобы вы могли писать любую функцию в бессмысленном стиле (Если у вас есть анализ случаев, доступный как функции, такие как maybe,either,bool). Опять,const играет роль введения константы. Вы можете увидеть эту работу в элемент данные.Функция.Молчаливый пакета.

скажем, вы хотите создать список Nothings равно длине строки. Как const возвращает свой первый аргумент, независимо от второго, вы можете сделать:

listOfNothings :: String -> [Maybe Char]
listOfNothings = (map . const) Nothing

или, более конкретно:

listOfNothing st = map (const Nothing) st