在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 Function
或closure 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 —> right
和right —> 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