답변:
나는 약간 투기 적이다 ...
문화 : 나는 |>
F # "문화"에서 중요한 연산자 라고 생각합니다 . 그리고 아마도 .
Haskell의 경우 와 유사 합니다. F #에는 함수 구성 연산자가 <<
있지만 F # 커뮤니티 는 Haskell 커뮤니티보다 포인트없는 스타일을 덜 사용하는 경향이 있다고 생각합니다 .
언어 차이 : 비교할 두 언어에 대해 충분히 알지 못하지만 let-bindings를 일반화하는 규칙은 이것에 영향을 미칠만큼 충분히 다를 수 있습니다. 예를 들어 F #에서 가끔
let f = exp
컴파일되지 않으며 명시적인 eta-conversion이 필요합니다.
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
이 알려진 유형으로 이어 지기 때문에 잘 작동합니다 .
.NET Framework와 같은 구문에 포함 된 이름 확인 때문에 왼쪽에서 오른쪽 형식 검사가 필요합니다 x.Value
. Simon Peyton Jones는 Haskell에 비슷한 종류의 이름 확인을 추가하기위한 제안 을 작성 했지만 대신 로컬 제약 조건을 사용하여 유형이 특정 작업을 지원하는지 여부를 추적 할 것을 제안합니다. 요구 사항 첫 번째 샘플에 따라서 x
필요 Value
속성이 될 때까지 이월 될 xs
보였다 이러한 요구 사항이 해결 될 수있다. 그러나 이것은 유형 시스템을 복잡하게 만듭니다.
더 많은 추측, 이번에는 주로 Haskell 측에서 ...
($)
의 뒤집기이며 (|>)
포인트 프리 코드를 작성할 수 없을 때 자주 사용됩니다. 따라서 (|>)
Haskell에서 사용되지 않는 주된 이유 는 그 자리가 이미 ($)
.
또한 약간의 F # 경험 을 살펴보면 OO (|>)
의 Subject.Verb(Object)
구조 와 비슷하기 때문에 F # 코드에서 매우 인기가 있다고 생각 합니다. F #은 원활한 기능 / OO 통합을 목표로하기 때문에 Subject |> Verb Object
새로운 기능 프로그래머에게 매우 부드러운 전환입니다.
개인적으로 나도 왼쪽에서 오른쪽으로 생각하는 것을 좋아하기 때문에 (|>)
Haskell에서 사용하지만 다른 사람들은 그렇게 생각하지 않습니다.
Data.Sequence.|>
, 그러나 $>
충돌이를 방지하기 위해 합리적인 보인다. 솔직히 잘 생긴 연산자가 너무 많기 때문에 |>
둘 다 사용 하고 사례별로 충돌을 관리합니다. (또한 그냥 별명에 유혹 될 수 Data.Sequence.|>
로 snoc
)
($)
및 (|>)
응용 프로그램이 아닙니다 구성된다. 두가 (당신이 (질문 노트로) 관련 그러나 그들은 동일하지 않습니다되어 fc
있다 (Control.Arrow.>>>)
기능).
|>
실제로 F # 은 실제로 |
다른 무엇보다 UNIX를 떠올리게 합니다.
|>
F # 의 또 다른 이점은 Visual Studio의 IntelliSense에 대한 멋진 속성이 있다는 것입니다. 를 입력 |>
하면 왼쪽의 값에 적용 할 수있는 함수 목록이 표시됩니다 .
. 이는 객체 뒤에 입력 할 때 발생하는 것과 유사 합니다.
나는 우리가 헷갈리는 것 같아요. Haskell의 ( .
)는 F # 의 ( )와 같습니다 >>
. 역함수 |>
응용 프로그램이며 Haskell의 ( $
) 와 같은 F #의 ( ) 와 혼동하지 마십시오 .
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 #의 파이프 라인과 동등 하게됩니다. 예를 들어 당신은 할 수 있습니다[1..10] |> map f
.
)는 ( )와 같고 <<
( >>
)는 역 구성입니다. 그것은 ( >> ) : ('T1 -> 'T2) -> ('T2 -> 'T3) -> 'T1 -> 'T3
대( << ) : ('T2 -> 'T3) -> ('T1 -> 'T2) -> 'T1 -> 'T3
.
동일합니다 >>
. F #에 있는지 모르겠지만 <<
Elm에서와 같이 동등한 것입니다.
|>
Haskell에서 F #을 사용하려면 Data.Function 에서 &
연산자입니다 ( base 4.8.0.0
).
&
을 통해 |>
? 나는 기분이 |>
훨씬 더 직관적이며, 또한 유닉스 파이프 연산자 생각 나게한다.
어떤 사람들은 Haskell에서도 왼쪽에서 오른쪽 (메시지 전달) 스타일을 사용합니다. 예를 들어 Hackage의 mps 라이브러리를 참조하십시오 . 예 :
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 #의 파이프 포워드 연산자 ( |>
)는 하스켈에서 ( & ) 와 비교해야 한다고 생각 합니다 .
// 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 = 중위 + 왼쪽 연관성
중위 자 = 중위 + 오른쪽 연관성
( .
)는 기능 구성을 의미합니다. 그 의미 (FG) (X) =를 (g (x)는 F) 연산이다.
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
( $
) 연산자는 데이터 함수 ($) 에서도 정의됩니다 .
( .
)는 작성 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]
와, Less (코드)가 더 좋습니다.
|>
하고.
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 지원 :
오늘은 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
&
하스켈의입니다|>
. 이 실에 깊숙이 묻혀서 발견하는 데 며칠이 걸렸습니다. 코드를 따르기 위해 자연스럽게 왼쪽에서 오른쪽으로 읽기 때문에 많이 사용합니다.