Haskell的组合物VS F#的管向前运算符(。)(|>)(Haskell composit

2019-07-18 21:48发布

在F#中使用的管道进运营商, |>是很常见的。 然而,在Haskell我只看过功能组成, (.)被使用。 据我所知,他们是相关的 ,但有一个语言的原因,管着是不是在Haskell使用或者是别的东西?

Answer 1:

我是一个小投机...

文化 :我想|>是在F#“文化”的重要运营商,也许同样有. Haskell的。 F#有一个功能复合算<<但我认为F#社区倾向于使用免费的点式小于哈斯克尔社区。

语言差异 :我不知道有足够的了解这两种语言进行比较,但也许对于推广让-绑定规则是十分不同的影响这一点。 例如,我知道F#有时写作

let f = exp

将不会编译,你需要明确的ETA-转换:

let f x = (exp) x   // or x |> exp

让它编译。 这还用于指导人们远离自由点-/作曲风格,并朝着流水线方式。 此外,F#类型推断有时需要流水线,使已知类型左侧出现(见这里 )。

(就个人而言,我觉得自由点式阅读,但我想,每一个新的/不同的事情似乎无法读取,直到你成为习惯了。)

我认为无论是潜在可行的两种语言,历史/文化/事故可以定义为什么每个社区在不同的“吸引”落户。



Answer 2:

在F# (|>)是因为左到右类型检查的重要。 例如:

List.map (fun x -> x.Value) xs

一般不会进行类型检查,因为即使类型xs是已知的,参数的类型x的拉姆达不是在typechecker看到它时已知的,所以它不知道如何解决x.Value

相反

xs |> List.map (fun x -> x.Value)

将正常工作,因为类型xs将导致类型x是已知的。

左到右类型检查是必需的,因为参与类似结构的名称解析的x.Value 。 西蒙佩顿琼斯写了一个建议添加类似的一种名称解析哈斯克尔的,但他建议使用局部约束跟踪类型是否支持特定的操作与否,来代替。 因此,第一个样品在要求x需要一个Value属性将被发扬光大,直到xs被认为和这个要求是可以解决的。 这确实类型系统虽然复杂。



Answer 3:

更多的猜测,这一次从主要哈斯克尔方...

($)是翻转(|>)它的使用是很常见的,当你不能写无点的代码。 因此,主要的原因是(|>) Haskell中不使用的是它的位置已经采取的($)

此外,从一点点F#的经验来说,我认为(|>)是F#代码,所以受欢迎,是因为它类似于Subject.Verb(Object) OO的结构。 由于F#的目标是平稳的功能/ OO整合, Subject |> Verb Object是新功能的程序员相当平稳过渡。

就个人而言,我喜欢思考左向右过,所以我用(|>)在Haskell,但我不认为很多其他人做。



Answer 4:

我认为我们困惑的事情。 Haskell的( . )等同于F#的( >> )。 不要与F#的混淆( |>这是刚刚反转的功能应用,犹如Haskell的() $ ) -逆转:

let (>>) f g x = g (f x)
let (|>) x f = f x

我相信哈斯克尔程序员使用$频繁。 也许不是经常为F#程序员倾向于使用|> 在另一方面,一些F#的家伙用>>到可笑的程度: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspx



Answer 5:

如果你想使用F#的|>哈斯克尔那么Data.Function是&运营商(因为base 4.8.0.0 )。



Answer 6:

左到右在Haskell组成

有些人用左到右(消息传递)风格在Haskell过。 见,例如, MPS上Hackage库。 一个例子:

euler_1 = ( [3,6..999] ++ [5,10..999] ).unique.sum

我觉得这种风格看起来在某些情况不错,但它读更难(需要知道库及其所有运营商,重新定义(.)被扰乱过)。

也有左到右以及从右到左组合物运营Control.Category ,底座包的一部分。 比较>>><<<分别为:

ghci> :m + Control.Category
ghci> let f = (+2) ; g = (*3) in map ($1) [f >>> g, f <<< g]
[9,5]

有一个很好的理由,有时更喜欢左到右的组成:评估顺序如下读取顺序。



Answer 7:

我见过>>>被用于flip (.)我经常用我自己,特别是对于长链,是最好的理解左到右。

>>>实际上是从Control.Arrow,和作品的不仅仅是功能更多。



Answer 8:

除了风格和文化,这归结为优化语言设计,无论是纯或不纯的代码。

|>运营商在F#中常见的主要是因为它有助于隐藏与主要-不纯的代码将出现两个限制:

  • 左到右类型推断无器质性亚型。
  • 值的限制。

需要注意的是前者限制不OCaml中存在,因为子类型是结构性的,而不是名义上的,这样的结构类型是通过统一容易精制类型推断的进展。

哈斯克尔采取了不同的权衡,选择把重点放在主要 - 纯代码,其中这些限制可以解除。



Answer 9:

这是我第一天去尝试哈斯克尔(锈后和F#),我是能够定义F#的|>操作:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 0 |>

它似乎工作:

factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)

main =     
    5 |> factorial |> print

我敢打赌,Haskell的专家可以给你一个更好的解决方案。



Answer 10:

我认为,F#的管道运营商前进( |>应VS ()在Haskell。

// pipe operator example in haskell

factorial :: (Eq a, Num a) =>  a -> a
factorial x =
  case x of
    1 -> 1
    _ -> x * factorial (x-1)

// terminal
ghic >> 5 & factorial & show

如果你不喜欢( & )运算符,你可以定制它像F#或药剂:

(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 1 |>
ghci>> 5 |> factorial |> show

为什么infixl 1 |> 看到在doc 数据的函数(&)

infixl =缀+左结合

infixr =缀+右结合


(。)

. )指的功能的组合物。 这意味着(FG)(X)= F(G(X))中的数学。

foo = negate . (*3)
// ouput -3
ghci>> foo 1
// ouput -15
ghci>> foo 5

它等于

// (1)
foo x = negate (x * 3) 

要么

// (2)
foo x = negate $ x * 3 

$ )运营商也defind在数据的函数($) 。

. )被用于创建Hight Order Functionclosure in js 。 见例如:


// (1) use lamda expression to create a Hight Order Function
ghci> map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]


// (2) use . operator to create a Hight Order Function
ghci> map (negate . abs) [5,-3,-6,7,-3,2,-19,24]  
[-5,-3,-6,-7,-3,-2,-19,-24]

哇,以下(代码)是更好的。


比较|>.

ghci> 5 |> factorial |> show

// equals

ghci> (show . factorial) 5 

// equals

ghci> show . factorial $ 5 

这是间不同的left —> rightright —> left 。 ⊙﹏⊙|||

人性化

|>&好过.

因为

ghci> sum (replicate 5 (max 6.7 8.9))

// equals

ghci> 8.9 & max 6.7 & replicate 5 & sum

// equals

ghci> 8.9 |> max 6.7 |> replicate 5 |> sum

// equals

ghci> (sum . replicate 5 . max 6.7) 8.9

// equals

ghci> sum . replicate 5 . max 6.7 $ 8.9

如何在面向对象语言函数式编程?

请访问http://reactivex.io/

IT支持 :

  • Java的:RxJava
  • JavaScript的:RxJS
  • C#:Rx.NET
  • C#(统一):UniRx
  • 斯卡拉:RxScala
  • Clojure的:RxClojure
  • C ++:RxCpp
  • LUA:RxLua
  • 红宝石:Rx.rb
  • 的Python:RxPY
  • 去程:RxGo
  • Groovy:在RxGroovy
  • JRuby的:RxJRuby
  • 科特林:RxKotlin
  • 斯威夫特:RxSwift
  • PHP:RxPHP
  • 药剂:reaxive
  • 飞镖:RxDart


文章来源: Haskell composition (.) vs F#'s pipe forward operator (|>)