2012-01-01 6 views
7

저는 하스켈을 처음 접했고 몇 가지 자습서를 시도하고 있습니다. 나는이 스크립트를 썼다 :Haskell에서 함수를 정의하는 올바른 방법

lucky::(Integral a)=> a-> String 
lucky 7 = "LUCKY NUMBER 7" 
lucky x = "Bad luck" 

내가 lucky.hs로이 저장되고 인터프리터를 실행하고 그것을 잘 작동합니다.

하지만 함수 정의가 확실하지 않습니다. 그것은 내가 다음과 같이 내가 똑같이 기능 운 정의 할 수 있습니다 읽었습니다 작은에서 보인다 (함수 이름은 lucky2입니다) :

lucky2::(Integral a)=> a-> String 
lucky2 x=(if x== 7 then "LUCKY NUMBER 7" else "Bad luck") 

모두 동일하게 작동하는 것. 명확하게 기능을 행운의 읽을 수 있지만 럭키 2 함수를 작성하는 올바른 방법은 무엇입니까?

+4

내가 아는 한, 그들은 의미가 같지만 첫 번째 것은 더 멋지게 보이고 하스켈에서 선호하는 방법입니다. 저는 하스켈 숙달이 아니며 잘못되었을 수도 있기 때문에 답변으로 게시하지 않을 것입니다. – Matej

+0

그건 그렇고, 괄호는 필요 없습니다.''lucky2 x = if x == 7 then "Lucky Number 7"else "Bad luck"' – sdcvvc

+0

또한 타입을''lucky :: Integral -> String' . '=>'의 왼쪽에있는 이름 짓기는 같은 유형이 두 번 필요할 경우를위한 것입니다. –

답변

14

둘 다 정확합니다. Haskell은 매우 유용한 기능인 패턴 일치을 사용하기 때문에 첫 번째 것은 더 숙련 된 하스켈입니다. 밑줄은 당신이 당신의 매개 변수의 정확한 형식 (값)을 무시하고 있다는 사실을 의미

lucky::(Integral a)=> a-> String 
lucky 7 = "LUCKY NUMBER 7" 
lucky _ = "Bad luck" 

:로이 형식에서, 그것은 일반적으로 기록 될 것입니다. 이전 선언에 의해 캡쳐 된 패턴 인 7과 다를뿐입니다.


패턴 일치의 중요성은 목록과 같이 더 복잡한 데이터에서 작동하는 기능에 의해 가장 잘 설명됩니다.

len [] = 0 

[] 절은 설정되어있는 패턴이 빈 목록과 일치하는 것입니다 : 당신은 예를 들어,리스트의 길이를 계산하는 함수를 작성한다면, 당신은 가능성이 빈 목록에 대한 변형을 제공함으로써 시작할 것 . 빈리스트는 분명히 길이가 0이므로, 우리는 함수를 반환 할 것입니다. 여기

len (x:xs) = 1 + len xs 

, 당신은 패턴 (x:xs)에 일치됩니다

len의 다른 부분은 다음과 같은 것이다. 콜론 :은 소위 cons 연산자 : 목록에 값을 추가합니다. 따라서 표현 x:xs은 어떤 요소 (x)가 일부 목록 (xs)에 추가되는 패턴과 일치하는 패턴입니다. 전체적으로 적어도 하나의 요소를 가진 목록과 일치합니다. xs 또한 빈 목록 ([]) 일 수 있기 때문입니다.

len의 두 번째 정의도 매우 간단합니다. 나머지리스트 (len xs)의 길이와 그 첫 번째 요소 (x)에 해당하는 1로 계산합니다.

(일반적인 방법은 위의 정의가 될 것이다 쓰기 : 다시 당신이 존재하는 것만, 첫 번째 요소가 무엇인지 상관하지 않는 것을 의미

len (_:xs) = 1 + len xs 

을).

+0

불행히도, 당신은 목록 길이를 계산하기위한 나쁜 방법을 보여줍니다. – Ingo

+5

잉고, 위트? 심지어 표준. 라이브러리는 다음과 같이이 작업을 수행합니다. [genericLength] (http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#genericLength). 'Int' 나 다른 타입들에 대해서 최적화를 할 수는 있지만 ('strictGenericLength'를보십시오), 점근 적 시간 요구 사항을 변경하지는 않습니다. – Rotsor

7

이 작성하는 세번째 방법은 가드를 사용하는 것입니다 : 그것에 대해 혼동하는 이유가

lucky n 
    | n == 7 = "lucky" 
    | otherwise = "unlucky" 

없습니다. 항상 1 가지 이상의 방법이 있습니다. 패턴 일치 또는 가드가없고 이있는 경우에도 if을 사용하는 경우에도 마찬가지입니다.

우리가 지금까지 다루었던 모든 양식은 하스켈이 제공 한 구문 설탕을 사용합니다. 패턴 가드는 여러 개의 함수 절 및 if 표현식뿐만 아니라 일반 사례 표현식으로 변환됩니다. 따라서 가장 낮은 수준, unsugared 방법이 아마도 것이다 쓰기 :

lucky n = case n of 
    7 -> "lucky" 
    _ -> "unlucky" 

당신이 내가 가장 그를 위해 일하는 어떤 그가 사용하는 초보자에게 권하고 싶습니다 관용적 방법에 대해 확인하는 것이 좋다하지만 어떤 그는 최선을 이해합니다. 예를 들어, 자유 스타일을 가리키는 (아직) 지식이 없다면, 그것을 강제 할 이유가 없습니다. 그것은 조만간 당신에게 올 것입니다.

관련 문제