2010-06-25 2 views
3

나는 어제 haskell을 배우기 시작했는데 문제가 생겼다. 조금씩 다른 것을 시도한 후에 나는 마침내 여기에 와서 이것을 고치는 법을 묻습니다. 또한 내가 지금까지 한 일들을 비판해서 자유롭게 어떤 방향으로 나아갈 지 알 수 있습니다. 감사.하스켈을 배우면서, 코딩 스타일을 도와 주겠니?

lessen :: Int -> Int 
    lessen a = ceiling (sqrt (fromIntegral a)) 

aInt을 입력 가지고 있지만, sqrt 다른 숫자에 필수적인 형식을 변환하는 부동 소수점 유형 및 쉬운 방법을 기대하고있다 :

module Main where 
main = putStrLn lastPrime 
    where 
     lastPrime :: String 
     lastPrime = show(last(take 10001 primes)) 
     primes :: [Int] 
     primes = [x| x <- [1..],length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2] 
     lessen :: Int -> Int 
     lessen a = ceiling(sqrt(a)) 
+3

향후에 발생하는 오류나 문제에 대해 설명해주십시오. – luqui

+0

아, 죄송합니다. 나는 완전히 잊었다. – BiscottiLighter

답변

7

당신의 유형의 오류를 해결하려면, 당신이 원하는 유형은 fromIntegral입니다.

length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2 

당신은 (당연히)까지만 lessen x에 요소를 고려하고 :

+0

신난다. 고쳐 줬다. 감사! – BiscottiLighter

+1

나는 하스켈에게 조금 익숙하다. 그러나 타입 유추는'lastPrime','primes','lessen'의 타입을 정확하게 표현할 필요가 없다는 것을 의미한다고 생각했습니다. –

+0

유형은 항상 * 정확한 *; 그러나 종종 암시 적 * 일 수 있습니다. 즉, 컴파일러에 의해 영향을받습니다. – jpaugh

4

lessen에서 유형 오류뿐만 아니라 당신은 소수의 논리 오류가 있습니다. 결과적으로 목록에 정확히 x - 2 개의 요소가 거의 없을 것입니다. 결과적으로 당신은 그리스트에서 두 개 이상의 요소를 얻으 려 할 때 무한 루프에 빠지게 될 것입니다 (왜냐하면 조건이 참인 3 번째 요소가 없기 때문에 haskell은이를 알지 못하기 때문에 무한 반복을 반복합니다). 그것을 찾으십시오).

목록의 길이를 취하는 것은 O(n) 작업이며 원하는 것을 성취하기위한 거의 항상 좋은 방법이 있습니다.

스타일 참고로 별도의 메서드 isPrime을 정의하는 것이 좋습니다. 이렇게하면 코드가 다음과 같이 표시됩니다.

module Main where 
main = putStrLn lastPrime 
    where 
     lastPrime :: String 
     lastPrime = show(last(take 10001 primes)) 
     isPrime x = length [a| a <- [1..lessen(x)], mod x a /= 0] == x - 2] 
     primes :: [Int] 
     primes = [x| x <- [1..], isPrime x] 
     lessen :: Int -> Int 
     lessen a = ceiling(sqrt (fromIntegral a)) 

이 IMHO를 사용하면 목록 이해가 훨씬 더 쉽게 읽을 수 있습니다. 그러나 여전히 버그가 있습니다. 버그를 없애기 위해 다른 접근법을 사용하여 isPrime을 정의하는 것이 좋습니다. lessen x으로 올라가는 것은 괜찮습니다. (모든 것이 1을 깨끗이 나누기 때문에 2에서 시작해야한다는 것을 제외하고) 모든 제수로 새 목록을 작성하는 대신, 범위 내의 숫자가 x를 나눈다는 것을 확인해야합니다. 이를 위해 더 높은 차수 함수 any을 사용할 수 있으므로 다음과 같이 표시됩니다.

isPrime x = not (any (\a -> mod x a == 0) [2 .. lessen x]) 
+0

고마워, 나는 haskell을 처음 접했고 함수 프로그래밍에 대한 내 머리를 감싸는 것은 좀 힘들다. – BiscottiLighter

+0

이것은 무엇을 위해 downvoted? – sepp2k