简体   繁体   English

以 pointfree 风格书写 fx = gxx

[英]Writing in pointfree style f x = g x x

I am learning Haskell.我正在学习 Haskell。 I'm sorry for asking a very basic question but I cant seem to find the answer.很抱歉问了一个非常基本的问题,但我似乎找不到答案。 I have a function f defined by :我有一个由以下定义的函数 f:

f x = g x x

where g is an already defined function of 2 arguments.其中 g 是一个已经定义的 2 个参数的函数。 How do I write this pointfree style?我如何编写这种 pointfree 风格? Edit : without using a lambda expression.编辑:不使用 lambda 表达式。

Thanks谢谢

f can be written with Control.Monad.join : f可以用Control.Monad.join编写:

f = join g

join on the function monad is one of the primitives used when constructing point-free expressions , as it cannot be defined in a point-free style itself (its SKI calculus equivalent, SIIap id id in Haskell — doesn't type) .函数 monad 上的join是构造无点表达式时使用的原语之一,因为它不能以无点样式本身定义(它的SKI 演算等价物, SII — Haskell 中的ap id id — 不输入)

This is known as "W" combinator :这被称为“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 are one basic set of combinators;S,K,I是一组基本的组合子; B,C,K,W are another - you've got to stop somewhere (re: your "no lambda expression" comment) : B、C、K、W是另一个——你必须在某个地方停下来(重新:你的“无 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
-}

I got here by pure chance, and I want to offer my solution, as nobody has mentioned lifting yet in this thread, not explicitly at least.我纯粹是偶然来到这里的,我想提供我的解决方案,因为没有人在这个线程中提到提升,至少没有明确提到。

This is a solution:这是一个解决方案:

f = liftM2 g id id

How to look at it?如何看待它?

  • g has type a -> a -> b , ie it takes two values of some type (the same type for both, otherwise the definition the OP gave of f wouldn't make sense), and gives back another value of some type (not necessarily of the same type as the arguments); g具有类型a -> a -> b ,即它需要某种类型的两个值(两者的类型相同,否则 OP 给出的f定义将没有意义),并返回某种类型的另一个(不一定与参数类型相同);

  • lift2M g is the lifted version of g and it has type (Monad m) => ma -> ma -> mb : it takes two monadic values , which are each a value in a so-far-unspecified context, and gives back a monadic value ; lift2M g是的抬起版本g ,它有式(Monad m) => ma -> ma -> mb :它需要两个一元值,它是每一个在一个所谓的远未指定的上下文中的值,并且给出了回一元值

  • when passing two functions to liftM2 g , the die is cast on what the context of the Monad is: it is that the values are not in there yet, but will eventually be, when the function will receive the arguments it needs;当将两个函数传递给liftM2 g ,取决于Monad的上下文是什么:这些值还没有在那里,但最终会在,当函数接收到它需要的参数时; in other words, functions are monads that store their own future values;换句话说,函数是存储自己未来值的 monad; therefore, lift2M g takes in input two functions (or, the future values of two functions), and gives back the another function (or, its future value );因此, lift2M g输入两个函数(或两个函数的未来值),并返回另一个函数(或它的未来值); knowing this, its type is the same as above if you change m to (->) r , or r -> : (r -> a) -> (r -> a) -> (r -> b)知道这一点,如果将m更改为(->) rr -> : (r -> a) -> (r -> a) -> (r -> b) ,则其类型与上述相同

  • the two functions that we pass are both id , which promises it'll give back the same value it receives;我们传递的两个函数都是id ,它承诺它会返回它接收到的相同值;

  • liftM2 g id id is therefore a function of type r -> b that passes its argument to those two id s, which let it unchanged and forward it to g .因此, liftM2 g id id是一个类型为r -> b的函数,它将其参数传递给这两个id ,使其保持不变并将其转发给g

In a similar fashion, one can exploit that functions are applicative functors, and use this solution:以类似的方式,可以利用函数是应用函子,并使用以下解决方案:

f = g <$> id <*> id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM