2011-11-02 2 views
3

형식 시그니처가있는 함수 정수/Int : "유형 정수가 Int와 일치하지 않습니다"

x :: Integer -> [a] -> [a] 
x = take 

y :: Integer -> [a] -> [a] 
y _ [] = [] 
y n xs = take n xs 

모두 Hugs 및 GHC보고 유형 오류 :

ERROR "test.hs":5 - Type error in application 
*** Expression  : take n xs 
*** Term   : n 
*** Type   : Integer 
*** Does not match : Int 

ERROR "test.hs":8 - Type error in explicitly typed binding 
*** Term   : x 
*** Type   : Int -> [a] -> [a] 
*** Does not match : Integer -> [a] -> [a] 

이는 "테이크"에 "Int -> ..."라는 서명이 있기 때문입니다. 타입 시스템이 (fromIntegral을 사용하지 않고) Integer를 Int로 직접 변환하거나 (Integer의 비 제한 크기를 유지하기 위해) 테이크 (또는 Int를 사용하여 명시 적으로 다른 함수를 "구성") for Integer? 아니면 Prelude-Functions의 자체 버전을 작성해야합니까? 현재, 내 코드는 fromIntegral (또는 Integer 크기가 Int의 차원을 초과하는 경우 실행되지 않음) 또는 표준 함수의 재 구현과 관련하여 매우 혼란 스럽습니다.

답변

4

대신 Data.List에서 genericTake을 사용하십시오. "일반"목록 함수는 Int 대신 Integer를받습니다. 이 유형의 서명에 의해 하스켈 기능을 검색 할 경우 당신이 원하는 모든 사용자가 사용할 수있는 변환 단계를 추가 할 경우

향후

, 당신은보다 일반적인 의미에서 Hoogle


을 사용할 수 있습니다 자신 만의 함수를 쉽게 생성 할 수있는 작성 연산자.

--explicit type signature to force the less general types... 
integerToInt :: Integer -> Int 
integerToInt = fromIntegral 

myGenericTake = take . integerToInt 

--You can now use myGenericTake throughout the code. 
+0

테이크는 단지 예일뿐입니다. 나는 아직도 하스켈을 배우고 있으며, 나는 대학에서 얻은 빈약 한 교육을 보완하려고 노력했다. 이것은 내가 스스로 비웃는 방식이다. 정수를 사용하여 x :: Int -> ...를 사용하려면 그럴 수 없습니까? (또는 fromIntegral을 사용하는 것만으로) –

+0

@Max : 함수 구성에 대해 조금 추가했습니다. – hugomg

+0

고맙습니다. 마지막 질문 : Haskell에게 특정 형식을 만났을 때 Prelude 함수 (또는 함수) 구현을 사용한다고 말하면 어떨까요? 나는 (예를 들어) 시그니처 take :: Integer -> ...와 함수 'take'를 쓰고 싶습니다. 그리고 Haskell이 적절할 때 그것을 선택하여 "myTake"나 "myTake"가 아닌 표준 이름을 사용할 수있게하십시오. 내 코드에서 "from .ntegral"을 가져옵니다. –

1

하스켈은 어떤 암시 적 캐스트를 만드는 하지의 접근 방식을 취하고. 따라서 take과 같은 함수가 붙어있는 경우 fromIntegral 또는 이와 유사한 형식을 사용하여 명시 적 형변환을 수행하려면 이 필요합니다.이 필요합니다.

버그가 있으면 Prelude 개선에 대한 의견을 말하십시오. 개선 된 Prelude 기능을 기대하는 것은 분명 혼자가 아닙니다.

관련 문제