Написание в стиле pointfree fx = gxx - PullRequest
16 голосов
/ 07 февраля 2012

Я учу Хаскель. Я прошу прощения за очень простой вопрос, но я не могу найти ответ. У меня есть функция F, определяемая как:

f x = g x x

где g - это уже определенная функция с 2 аргументами. Как мне написать этот стиль без смысла? Изменить: без использования лямбда-выражения.

Спасибо

Ответы [ 2 ]

20 голосов
/ 07 февраля 2012

f можно записать с помощью Control.Monad.join:

f = join g

join на монаде функции - это один из примитивов, используемых при построении бессмысленных выражений , поскольку он не может быть определен в самом стиле без точек (его исчисление SKI эквивалент, SII - ap id id в Haskell - не печатает) .

9 голосов
/ 15 июня 2012

Это известно как "W" комбинатор :

import Control.Monad
import Control.Monad.Instances
import Control.Applicative

f = join g       -- = Wg        (also, join = (id =<<))
  = (g `ap` id)  -- \x -> g x (id x) = SgI
  = (<*> id) g   --                  = CSIg
  = g =<< id     -- \x -> g (id x) x
  = id =<< g     -- \x -> id (g x) x

S, K, I - один базовый набор комбинаторов; B, C, K, W - это другое - вам нужно остановиться где-нибудь (re: ваш комментарий «без лямбда-выражения»)

_B = (.)     -- _B f g x = f (g x)     = S(KS)K
_C = flip    -- _C f x y = f y x       = S(S(K(S(KS)K))S)(KK)
_K = const   -- _K x y   = x
_W = join    -- _W f x   = f x x       = CSI = SS(KI) = SS(SK)
_S = ap      -- _S f g x = f x (g x)   = B(B(BW)C)(BB) = B(BW)(BBC)
   = (<*>)                                -- from Control.Applicative
_I = id      -- _I x     = x           = WK = SKK = SKS = SK(...)

{-
Wgx = gxx 
    = SgIx = CSIgx 
           = Sg(KIg)x = SS(KI)gx
    = gx(Kx(gx)) = gx(SKgx) = Sg(SKg)x = SS(SK)gx

-- _W (,) 5 = (5,5)
-- _S _I _I x = x x = _omega x         -- self-application, untypeable
-}
...