Відповіді:
Я трохи роздумую ...
Культура : Я думаю |>
, що це важливий оператор у F # "культурі", а можливо, аналогічно з .
Haskell. F # має оператор композиції функцій, <<
але я думаю, що спільнота F # має тенденцію використовувати стиль без точок менше, ніж у спільноти Haskell.
Мовні відмінності : я не знаю достатньо обох мов для порівняння, але, можливо, правила узагальнення прив’язок є досить різними, щоб вплинути на це. Наприклад, я знаю, що в F # іноді пишу
let f = exp
не компілюється, і вам потрібна явна ета-конверсія:
let f x = (exp) x // or x |> exp
змусити його складати. Це також відволікає людей від стилю, що не належить до очок / композиції, та до конвеєрного стилю. Також висновок типу F # іноді вимагає конвеєрного руху, так що відомий тип з’являється зліва (див. Тут ).
(Особисто я вважаю, що стиль без очок не читається, але я вважаю, що кожна нова / інша річ здається нечитабельною, поки ти не звикнеш до неї.)
Я думаю, що обидва є потенційно життєздатними на будь-якій мові, і історія / культура / нещасний випадок може визначити, чому кожна громада оселилася на різному «притягувачі».
.
і $
, тому люди продовжують їх використовувати.
У F # (|>)
важливо через перевірку типу "зліва направо". Наприклад:
List.map (fun x -> x.Value) xs
як правило, не буде перевірено набір тексту, оскільки навіть якщо тип xs
відомий, тип аргументу x
лямбда не відомий у той момент, коли його перевіряє, тому він не знає, як вирішити x.Value
.
У контрасті
xs |> List.map (fun x -> x.Value)
буде добре працювати, тому що тип xs
водіння призведе до типу x
відомого.
Перевірка типу вліво-вправо потрібна через роздільну здатність імен, що беруть участь у таких конструкціях x.Value
. Саймон Пейтон Джонс написав пропозицію щодо додавання подібного виду дозволу імені до Haskell, але він пропонує використовувати локальні обмеження, щоб відстежувати, підтримує якийсь тип певну операцію чи ні. Тож у першому зразку вимога, яка x
потребує Value
властивості, переноситиметься до тих пір, поки xs
не буде видно, і ця вимога може бути вирішена. Це, однак, ускладнює систему типів.
Більше спекуляцій, цього разу з боку переважно Хаскелл ...
($)
це фліп (|>)
, і його використання є досить поширеним, коли ви не можете написати безточний код. Отже, головна причина, що (|>)
не використовується в Haskell, полягає в тому, що її місце вже зайнято ($)
.
Крім того, кажучи з трохи досвіду F #, я думаю (|>)
, що такий популярний у F # коді, оскільки він нагадує Subject.Verb(Object)
структуру ОО. Оскільки F # має на меті плавну функціональну / інтеграцію OO, Subject |> Verb Object
це досить плавний перехід для нових функціональних програмістів.
Особисто мені теж подобається думати зліва направо, тому я використовую (|>)
в Haskell, але я не думаю, що так багато інших людей.
Data.Sequence.|>
, але $>
здається розумним уникати конфліктів там. Чесно кажучи, є лише стільки гарних операторів, тому я просто використовую |>
для обох і керую конфлікти в кожному конкретному випадку. (Крім того, я був би спокуса просто псевдонім , Data.Sequence.|>
як snoc
)
($)
і (|>)
є застосуванням не складом. Два пов'язані (як питання примітки) , але вони не збігаються (ваше fc
є (Control.Arrow.>>>)
для функцій).
|>
насправді більше нагадує мені UNIX, |
ніж будь-що інше.
|>
F # є те, що він має приємні властивості для IntelliSense у Visual Studio. Введіть |>
і ви отримаєте список функцій, які можна застосувати до значення зліва, подібного до того, що відбувається під час введення тексту .
після об’єкта.
Я думаю, що ми плутаємо речі. Haskell's ( .
) еквівалентний F # 's ( >>
). Не плутати з F # 's ( |>
), який є просто перевернутим додатком функції і схожий на Haskell ( $
) - зворотний:
let (>>) f g x = g (f x)
let (|>) x f = f x
Я вважаю, що програмісти Haskell $
часто використовують часто. Можливо, не так часто, як зазвичай використовують програмісти F # |>
. З іншого боку, деякі хлопці F # >>
до смішного рівня використовують: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspx
$
оператор - звернуто, ви можете легко визначити його як: a |> b = flip ($)
яке стає еквівалентно F # 's трубопроводу , наприклад , ви можете зробити[1..10] |> map f
.
) те саме, що ( <<
), тоді як ( >>
) - зворотний склад. Це ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
проти( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
це рівнозначно >>
. Я не знаю, чи є F #, <<
але це було б еквівалентом (як у Elm).
Якщо ви хочете використовувати F # 's |>
в Haskell, то в Data.Function є &
оператором (з тих пір base 4.8.0.0
).
&
більш |>
? Я відчуваю, що |>
набагато інтуїтивніше, і це також нагадує мені оператора труб Unix.
Деякі користуються стилем зліва направо (передача повідомлень) і в 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]
Існує вагома причина, щоб іноді віддавати перевагу композиції зліва направо: оцінка порядку дотримується порядку читання.
Я бачив, як >>>
його використовують flip (.)
, і я часто це використовую сам, особливо для довгих ланцюгів, які найкраще розуміють зліва направо.
>>>
насправді від Control.Arrow і працює над більш ніж просто функціями.
>>>
визначено в Control.Category
.
Окрім стилю та культури, це зводиться до оптимізації мовного дизайну для чистого чи нечистого коду.
|>
Оператор часто зустрічається в F # в основному тому , що це допомагає приховати два обмеження , які з'являються з переважно-нечистим кодом:
Зауважимо, що колишнє обмеження не існує в OCaml, оскільки підтипізація є структурною замість номінальної, тому структурний тип легко уточнюється за допомогою уніфікації в міру просування виводу типу.
Haskell робить інший компроміс, вирішивши зосередитись на переважно чистому коді, де ці обмеження можна зняти.
Я думаю, що оператор F #'s pipe forward ( |>
) повинен проти ( & ) у 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 # або Elixir:
(|>) :: a -> (a -> b) -> b
(|>) x f = f x
infixl 1 |>
ghci>> 5 |> factorial |> show
Чому infixl 1 |>
? Див. Документ у функції даних (&)
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
( $
) Оператор також визначається в Data-Function ($) .
( .
) використовується для створення 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/
Він підтримує:
Це мій перший день спробувати Haskell (після Rust і 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 може дати вам ще краще рішення.
x |> f = f x
&
це Хаскелл|>
. Заглибився глибоко в цю нитку і знадобився мені кілька днів, щоб відкрити. Я його дуже використовую, тому що ви, природно, читаєте зліва направо, щоб слідувати коду.