以无点样式写作f x = g x x

时间:2012-02-06 23:45:27

标签: haskell pointfree

我正在学习Haskell。我很抱歉提出一个非常基本的问题,但似乎无法找到答案。我有一个函数f定义:

f x = g x x

其中g是已定义的2个参数的函数。我如何写这个免费的风格? 编辑:不使用lambda表达式。

由于

3 个答案:

答案 0 :(得分:20)

f可以使用Control.Monad.join编写:

f = join g
函数monad上的

join是构造无点表达式时使用的原语之一,因为它不能以无点样式本身定义(它的SKI calculus等价物,{ {1}} - Haskell中的SII - 不输入)

答案 1 :(得分:9)

这称为"W" combinator

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:你的“没有lambda表达”评论)

_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
-}

答案 2 :(得分:1)

我纯属偶然来到这里,我想提供自己的解决方案,因为没有人提到此线程中提升,至少没有明确提及。

这是一个解决方案:

f = liftM2 g id id

如何看待它?

  • g的类型为a -> a -> b,即,它需要两个相同类型的值(两者的类型相同,否则,OP给{{ 1}}毫无意义),并返回其他某种类型的(不一定是与参数相同的类型);

  • flift2M g的提升版本,类型为g:它需要两个Monadic值,每个值都是一个迄今未指定的上下文,并返回一元数值;

  • 当将两个函数传递给(Monad m) => m a -> m a -> m b时,模子将基于liftM2 g的上下文是:值尚未存在,但最终会存在,函数何时将收到所需的参数;换句话说,函数是存储它们自己未来值的单子。因此,Monad接受两个函数的输入(或者两个函数的将来值),并返回另一个函数(或者其未来值) ;知道这一点后,如果将lift2M g更改为m(->) rr ->

  • ,其类型与上面相同
  • 我们传递的两个函数都是(r -> a) -> (r -> a) -> (r -> b),这保证它会返回与接收到的相同的值;

  • 因此,
  • id是类型liftM2 g id id的函数,它将其参数传递给这两个r -> b,使它们不变并转发给id

以类似的方式,可以利用功能是应用函子,并使用此解决方案:

g