2016-10-05 12 views
0

나는 짧은 하스켈 프로그램을 작성하고 문제

import System.Random 
func1=getStdRandom $ randomR ('A','Z') 
main = do 
    print =<< func1 

없이 컴파일하지만 (1100)에 튜플을 변경 한 경우, 나는 성공적으로 컴파일하기 위해 유형 서명을 추가해야합니다.

import System.Random 
func2 :: IO Int 
func2=getStdRandom $ randomR (1,100) 
main = do 
    print =<< func2 

기능 유형이 다릅니다.

Prelude System.Random> func1 = getStdRandom $ randomR ('A','Z') 
Prelude System.Random> func2 = getStdRandom $ randomR (1,100) 
Prelude System.Random> func3 = getStdRandom $ randomR (1,100) :: IO Int 
Prelude System.Random> :t func1 
func1 :: IO Char 
Prelude System.Random> :t func2 
func2 :: (Random a, Num a) => IO a 
Prelude System.Random> :t func3 
func3 :: IO Int 
Prelude System.Random> 

누군가 두 개의 유사한 찾고 튜플 (Char, Char) 및 (Int, Int)가 다른 유형 서명 함수를 생성하는 이유를 설명해 줄 수 있습니까?

그리고 함수를 옮기면 컴파일되지 않습니다.

import System.Random 
main = do 
print =<< getStdRandom $ randomR ('A','Z') 

나도 몰라 왜 "인쇄 = < < FUNC1"작동하지만 "인쇄 = < < getStdRandom $ randomR ('A', 'Z')가"작동하지 않는 경우 FUNC1와 "getStdRandom $ randomR ('A', 'Z') "는 같은 것입니까? 당신이이 Num typeclass의 인스턴스 중 하나가 될 수 하스켈의 문자 수를 쓸 때

는 EII

답변

4

감사드립니다. 이것은 Float, Double, Int, Integer 등을 포함합니다. 따라서 컴파일러는 어느 Num에 대해 이야기하고 있는지 알지 못하므로 Int을 지정해야합니다. 반면에 문자 리터럴은 항상 Char이므로 형식을 지정할 필요가 없습니다.

+0

감사합니다. DiegoNolan – eii0000

2
Prelude System.Random> getStdRandom $ randomR (1,100) :: IO Int 
88 
Prelude System.Random> getStdRandom $ randomR (1,100) :: IO Double 
10.275865473218671 
3

누군가가 나에게 없었던 이유를 두 유사하게 보이는 튜플 (숯불, 숯불) 및 (INT, INT) 다른 종류의 서명 기능을 생성? 특정 유형이 문맥에서 추론 할 수없는 하스켈의 모든 숫자 리터럴 다형성 때문에

(1, 100) 같은 튜플 유형 (Int, Int)이 없습니다.

나도 몰라 왜 "인쇄 = < < FUNC1"작동하지만 "인쇄 = < < getStdRandom $ randomR ('A', 'Z')가"작동하지 않습니다 경우 FUNC1와 "getStdRandom $ randomR ('A', 'Z') "같은 것이 있습니까?

연산자 우선 순위 때문입니다.

print =<< getStdRandom $ randomR ('A','Z') 

은 다음과 같이 해석한다 :

(print =<< getStdRandom) $ (randomR ('A','Z')) 

당신이 원하는 것은 :

print =<< (getStdRandom $ randomR ('A','Z')) 
1

누군가가 나에게 없었던 이유를 두 유사하게 보이는 튜플 (숯불, 숯불) 및 (INT, Int) 다른 형식 시그니처 함수를 생성합니까?=> 전에

Prelude> :t 1 
1 :: Num t => t 

부분은 유형 제약 조건입니다 :

하스켈에서 중요한 리터럴은 실제로 유형 Num t => t 있습니다. 유형 tNum 클래스를 구현해야합니다. 그리고 => 뒤에있는 부분이이 경우에는 단지 t입니다. 즉, 문자 1은 클래스를 구현하는 모든 유형 t을 가질 수 있습니다.

타입 클래스는 한 타입이이 경우와 같은 함수 집합을 지원한다는 것을 표현하는 방법입니다. Num 타입은 fromInteger :: Integer -> a 함수를 가져야 만합니다. 즉 구현하는 인스턴스 인 모든 타입이 a입니다. 하스켈은 이제 1에서 fromInteger 1까지와 같은 모든 중요한 리터럴을 desugars합니다. 여기서 1Integer입니다.

관련 문제