[haskell] 의 차이점은 무엇입니까? (점)과 $ (달러 기호)?

(.)과 달러 기호 의 차이점은 무엇입니까 ($)?

내가 이해하는 것처럼, 그들은 괄호를 사용할 필요가 없기 때문에 둘 다 구문 설탕입니다.



답변

$연산자는 괄호를 회피하기위한 것이다. 그 후에 나타나는 것은 앞에 오는 것보다 우선합니다.

예를 들어 다음과 같은 줄이 있다고 가정 해 봅시다.

putStrLn (show (1 + 1))

이러한 괄호를 제거하려면 다음 행 중 하나도 동일한 작업을 수행합니다.

putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1

.연산자 의 주요 목적은 괄호를 피하는 것이 아니라 함수를 연결하는 것입니다. 오른쪽에 나타나는 모든 출력을 왼쪽에 나타나는 모든 입력에 연결할 수 있습니다. 일반적으로 괄호가 적지 만 다르게 작동합니다.

같은 예로 돌아가서 :

putStrLn (show (1 + 1))
  1. (1 + 1)입력이 없으므로 .연산자 와 함께 사용할 수 없습니다 .
  2. show를 가져 와서 a Int를 반환 할 수 있습니다 String.
  3. putStrLn를 가져 String와서을 반환 할 수 있습니다 IO ().

다음 과 같이 체인 show을 연결할 수 있습니다 putStrLn.

(putStrLn . show) (1 + 1)

원하는 괄호가 너무 많으면 $연산자를 사용하여 제거하십시오 .

putStrLn . show $ 1 + 1


답변

유형과 정의가 다릅니다.

infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)

infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x

($)괄호를 피하기 위해 일반적인 함수 응용 프로그램을 대체하지만 다른 우선 순위를 갖습니다. (.)새로운 기능을 만들기 위해 두 개의 기능을 함께 구성하기위한 것입니다.

어떤 경우에는 상호 교환이 가능하지만 일반적으로 사실이 아닙니다. 이들이있는 전형적인 예는 다음과 같습니다.

f $ g $ h $ x

==>

f . g . h $ x

다시 말해서 $s 체인에서 , 마지막 체인을 제외한 모든 체인은.


답변

또한주의 ($)이다 기능 유형에 전문 신원 기능 . identity 함수는 다음과 같습니다.

id :: a -> a
id x = x

반면 ($)다음과 같다 :

($) :: (a -> b) -> (a -> b)
($) = id

타입 시그니처에 의도적으로 여분의 괄호를 추가했습니다.

($)연산자는 섹션에서 사용되지 않는 한 괄호를 추가하여 일반적으로 사용을 제거 할 수 있습니다. 예 : f $ g x됩니다 f (g x).

의 사용은 (.)대체하기가 약간 더 어렵다. 그들은 일반적으로 람다 또는 명시 적 함수 매개 변수의 도입이 필요합니다. 예를 들면 다음과 같습니다.

f = g . h

된다

f x = (g . h) x

된다

f x = g (h x)

도움이 되었기를 바랍니다!


답변

($) 평가 순서를 제어하기 위해 괄호를 추가하지 않고 함수를 함께 연결할 수 있습니다.

Prelude> head (tail "asdf")
's'

Prelude> head $ tail "asdf"
's'

compose 연산자 (.)는 인수를 지정하지 않고 새 함수를 작성합니다.

Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'

Prelude> let second = head . tail
Prelude> second "asdf"
's'

위의 예는 논쟁의 여지가 있지만 실제로는 컴포지션 사용의 편의성을 보여주지는 않습니다. 여기 또 다른 비유가 있습니다.

Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"

세 번째 만 한 번만 사용하면 람다를 사용하여 이름을 피할 수 있습니다.

Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"

마지막으로 구성은 람다를 피할 수 있습니다.

Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"


답변

짧고 달콤한 버전 :

  • ($) 오른쪽 인수 인 값에서 왼쪽 인수 인 함수를 호출합니다.
  • (.) 오른쪽 인수 인 함수에서 왼쪽 인수 인 함수를 구성합니다.

답변

유용하고 매우 짧은 설명 에서 알아 내는 데 시간이 걸리는 하나의 응용 프로그램은 haskell을 배우십시오 .

f $ x = f x

그리고 infix 연산자를 포함하는 표현식의 오른쪽을 괄호로 묶으면 접두사 함수로 변환 ($ 3) (4+)됩니다 (++", world") "hello".

왜 이런 짓을했을까요? 예를 들어 기능 목록. 양자 모두:

map (++", world") ["hello","goodbye"]`

과:

map ($ 3) [(4+),(3*)]

map (\x -> x ++ ", world") ...또는 보다 짧습니다 map (\f -> f 3) .... 분명히 후자의 변형은 대부분의 사람들이 더 읽기 쉽습니다.


답변

Haskell : .(점)과 $(달러 기호)의 차이점

(.)과 달러 기호 의 차이점은 무엇입니까 ($)? 내가 이해하는 것처럼, 그들은 괄호를 사용할 필요가 없기 때문에 둘 다 구문 설탕입니다.

그것들은 괄호를 사용할 필요 가 없어서 구문 설탕이 아닙니다-그것들은 함수이며, 따라서 우리는 그들을 연산자라고 부를 수 있습니다.

작성 (.)및 사용시기.

(.)작성 기능입니다. 그래서

result = (f . g) x

인수로 전달 결과 전달 함수 구축과 동일 g행 온 f.

h = \x -> f (g x)
result = h x

(.)작성하려는 함수에 전달할 인수가없는 경우에 사용하십시오 .

올바른 연관 적용 ($)및 사용시기

($)바인딩 우선 순위가 낮은 오른쪽 연관 적용 함수입니다. 따라서 단지 오른쪽에있는 것을 먼저 계산합니다. 그러므로,

result = f $ g x

절차 상으로 이것과 동일합니다 (Haskell이 게으르게 평가되기 때문에 중요합니다 f.)

h = f
g_x = g x
result = h g_x

더 간결하게 :

result = f (g x)

($)선행 함수를 결과에 적용하기 전에 평가할 모든 변수가있을 때 사용하십시오 .

우리는 각 기능의 소스를 읽음으로써 이것을 볼 수 있습니다.

소스를 읽으십시오

소스 는 다음과 같습니다 (.).

-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.)    :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)

그리고 여기에 대한 소스 가 있습니다 ($):

-- | Application operator.  This operator is redundant, since ordinary
-- application @(f x)@ means the same as @(f '$' x)@. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- >     f $ g $ h x  =  f (g (h x))
--
-- It is also useful in higher-order situations, such as @'map' ('$' 0) xs@,
-- or @'Data.List.zipWith' ('$') fs xs@.
{-# INLINE ($) #-}
($)                     :: (a -> b) -> a -> b
f $ x                   =  f x

결론

기능을 즉시 평가할 필요가없는 경우 구성을 사용하십시오. 컴포지션에서 생성 된 함수를 다른 함수로 전달하려고 할 수 있습니다.

전체 평가를 위해 모든 인수를 제공 할 때 응용 프로그램을 사용하십시오.

예를 들어, 의미 적으로는

f $ g x

우리가 x(또는 오히려 g논쟁을 할 때 ), 그리고 할 때 :

f . g

우리가하지 않을 때.