문제

실제 프로젝트를 사용하여 Haskell을 배우려고 노력하면서 다음과 같은 정의를 발견했습니다. 나는 각 인수 앞의 느낌표가 무엇을 의미하는지 이해하지 못하고 내 책은 언급하지 않은 것 같습니다.

data MidiMessage = MidiMessage !Int !MidiMessage
도움이 되었습니까?

해결책

엄격한 선언입니다. 기본적으로 데이터 구조 값이 생성 될 때 "약한 정상 헤드 형태"로 평가되어야 함을 의미합니다. 우리는 이것이 의미하는 바를 볼 수 있도록 예를 살펴 보겠습니다.

data Foo = Foo Int Int !Int !(Maybe Int)

f = Foo (2+2) (3+3) (4+4) (Just (5+5))

함수 f 위의 평가가 평가되면 "Thunk"를 반환합니다. 즉, 그 값을 파악하기 위해 실행하는 코드입니다. 그 시점에서 Foo는 아직 존재하지 않으며 코드 만 있습니다.

그러나 어느 시점에서 누군가는 아마도 패턴 일치를 통해 내부를 보려고 할 수 있습니다.

case f of
     Foo 0 _ _ _ -> "first arg is zero"
     _           -> "first arge is something else"

이것은 필요한 것을 수행하기에 충분한 코드를 실행할 것입니다. 따라서 4 개의 매개 변수가있는 Foo를 만듭니다 (기존 없이는 내부를 볼 수 없기 때문에). 첫 번째, 우리는 그것을 테스트하기 때문에 4, 우리가 그것이 일치하지 않는다는 것을 깨닫는 곳.

두 번째는 테스트하지 않기 때문에 평가할 필요가 없습니다. 따라서 6 해당 메모리 위치에 저장되면 나중에 평가할 수있는 코드를 저장합니다. (3+3). 누군가가 그것을 보는 경우에만 6으로 변할 것입니다.

그러나 세 번째 매개 변수에는 a가 있습니다 ! 그 앞에서는 엄격하게 평가됩니다. (4+4) 실행되고 8 해당 메모리 위치에 저장됩니다.

네 번째 매개 변수도 엄격하게 평가됩니다. 그러나 여기에 약간 까다로워지는 곳이 있습니다. 우리는 완전히 평가하지 않고 정상적인 헤드 형태만으로 평가하고 있습니다. 이것은 우리가 그것이 있는지 알아 낸다는 것을 의미합니다 Nothing 또는 Just 무언가를 보관하고 저장하지만 우리는 더 이상 가지 않습니다. 그것은 우리가 보관하지 않음을 의미합니다 Just 10 그러나 실제로 Just (5+5), 펑크를 비평가에 남겨 두었습니다. 이것은이 질문의 범위를 뛰어 넘는다고 생각하지만 이것은 아는 것이 중요합니다.

당신이 BangPatterns 언어 확장 :

f x !y = x*y

f (1+1) (2+2) 덩어리를 반환합니다 (1+1)*4.

다른 팁

엄격한 생성자 인수와 비 강력한 생성자 인수의 차이를 보는 간단한 방법은 정의 할 때 어떻게 행동하는지입니다. 주어진

data Foo = Foo Int !Int

first (Foo x _) = x
second (Foo _ y) = y

비 강력한 주장은 평가되지 않기 때문에 second, 통과 undefined 문제를 일으키지 않습니다.

> second (Foo undefined 1)
1

그러나 엄격한 주장은 될 수 없습니다 undefined, 값을 사용하지 않더라도 :

> first (Foo 1 undefined)
*** Exception: Prelude.undefined

나는 그것이 엄격한 주석이라고 생각합니다.

Haskell은 순수하고 게으른 기능적 언어이지만 때로는 게으른 오버 헤드가 너무 많거나 낭비 될 수 있습니다. 따라서이를 다루기 위해 컴파일러에게 펑크를 구문 분석하는 대신 기능에 대한 인수를 완전히 평가하도록 요청할 수 있습니다.

이 페이지에 대한 자세한 정보가 있습니다. 성능/엄격함.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top