2015-01-07 2 views
-1

나는 하스켈을 배우기 시작했습니다. 비록 내가 단조롭지 만, 나는이 일을하고자한다. 받은 오류가 제목으로 나열됩니다. 이 코드는 목록을 복제하는 동작을 구현하고 새로운 길이로 새로운 길이를 연결하려고 시도한 코드입니다. 이제 하스켈에서 구문 분석이 어떻게 작동하는지에 대한 기본적인 이해를 얻었습니다. 원래 코드 아래에서 구문 분석에 대한 필자의 지식이 적절한 지 확인하기 위해 수정 된 코드 예제를 제공 할 것입니다. 지금 제 질문은이 오류를받지 못하도록 블록을 들여 쓰거나 구조화하는 방법입니다 (O : 충분). 인스턴스 및 형식을 만들 때 누락되는 정보가 있습니까? 내 현재 상태 또는 주요 기능이 SYNTACTICALLY 잘못된 경우 제게 알려 주거나 제안을 제공하지 마십시오. 알아 내고 싶을 때 GHC 오류를 처리 할 것입니다. (이것이 올바른 학습 방법이라고 생각합니다.) 그러나 적절한 형식 지정을 이해하는 데있어 첫 번째 장애물을 극복하는 데 도움이 될 사람의 도움을 요청할 수 있다면 감사하게 생각합니다.구문 분석 오류 : (잘못된 들여 쓰기 또는 잘못 붙인 괄호)

module Main where 
import Data.List 

n :: Int 
x :: [Char] 

instance Data stutter n x where 
    x = [] 
    n = replicate >>= x : (n:xs) 
    stutter >>= main = concat [x:xs] 

let stutter 6 "Iwannabehere" -- <-- parse error occurs here!!! 

- 수정 된 코드는 적절한 괄호로 묶어야합니다.

module Main where 
import Data.List 

n :: Int 
x :: [Char] 

instance Data stutter n x where{ 
    ;x = [] 
    ;n = replicate >>= x : (n:xs) 
    ;stutter >>= main = concat [x:xs] 
; 
};let stutter 6 "Iwannabehere" -- there should be no bracket of any kind at the end of this 

내가 블록의 외부에 '하자'표현을 배치, 나는 그것이 내부 간다 믿지 않는 내가 그렇게한다면 나는 또한 구문 분석 오류가 발생합니다. 정확하지는 않지만 어쨌든 물어볼 거라고 생각했습니다.

+3

이 코드에는 많은 문제가 있습니다. 타입 시그니처는 정의가 뒤따라야하기 때문에 'n :: Int' 다음에'x'에 대한 시그니처가 올 바르지 않습니다. 둘째, 인스턴스 데이터를 선언하지만 데이터는이 범위에서 유형 클래스가 아닙니다. 셋째, 최상위 레벨 선언은 표현식이 될 수 없습니다. 즉, 'let'은 유효한 최상위 레벨 구조가 아닙니다. 어쩌면'LYAH'를 읽고 한 번에 한 가지 질문 만하고 시도해야 할 것입니다. –

+2

@ ThomasM.DuBuisson'n :: Int' 다음에'x :: Int'가 오는 것은 완벽하게 유효합니다. 정의는 동일한 파일에 있어야하며 서명에 직접 인접하지 않아도됩니다. – Cubic

+1

'let variable = value'는 GHCi와'do'-blocks만을위한 것입니다. 단순히'variable = value'라고 쓰면됩니다. 하스켈과 관련된 모든 것에 대해 더 알고 싶으면, http://learnyouahaskell.com/chapters를 방문하는 것이 좋습니다. – AJFarmar

답변

5

instance Data stutter n x이 무엇이 될지 잘 모르겠다. instance XYZ where 구문은 입력 전용으로 사용되지만 여기에는 몇 가지 구문 오류가 있습니다.

우선 GHC에서 오류가 let stutter 6 "Iwannabehere"이라고 말하면서 첫 번째 오류는 stutter >>= main = concat [x:xs]으로 발생합니다. 단일 = 부호는 단지 정의 인 할당을 위해 예약되어 있습니다. 할당 수준은 where 블록 내부 또는 let 블록 내부에있을 수 있습니다 (where에는 typeclass 인스턴스 정의가 포함됨). 과제는 x >>= y = z과 같은 표현식의 일부가 될 수 없습니다.

다음 구문 오류는 let입니다. let 블록은 최상위 레벨에 나타날 수 없으며 다른 정의 내에 만 나타납니다. GHCi에서 let을 사용하지만 그 이유는이 답변의 범위를 벗어납니다. GHCi에서 표현식을 입력하는 것이 소스 파일의 최상위 레벨과 일치하지 않는다고 말하기에 충분합니다.

다음으로 let 블록을 사용하면 정의 만 포함 할 수 있습니다. 구문은 더 비슷해 보입니다.

let <name> [<args>] = <definition> 
    [<name> [<args>] = <definition>] 
in <expression> 

그리고이 전체 블록이 표현을 만듭니다. 예를 들어, 파이썬에서

def f(x, y, z): 
    w = x + y + z 
    u = x - y - z 
    return w * u 

을 쓸 수 있습니다, 이것은 하스켈 함수 정의 그것은 로컬 변수를 정의

f x y z = let w = x + y + z 
       u = x - y - z 
      in w * u 

에 해당 될 것이다. 당신이 in <expression> 부분을 제외 할 수있는 당신이 여기 in를 사용할 필요가 없도록

main = do 
    name <- getLine 
    let message = if length name > 5 then "short name" else "long name" 
     goodbye n = putStrLn ("Goodbye, " ++ n) 
    putStrLn message 
    goodbye name 

참고로, do 블록 내부에 그것을 사용하고 다른 형태가있다.

main = do 
    name <- getLine 
    let message = ... 
     goodbye n = ... 
    in do 
     putStrLn message 
     goodbye name 

그리고이 같은 꽤되지 않습니다 : 당신은 당신은 당신이 새로운 do 블록을 시작해야 의미 할 수 있다면.

바라건대 이것은 올바른 구문을 더 잘 나타 내기를 바랍니다. 그러나 하스켈의 작동 방식에 대한 오해가있는 것 같습니다. Learn You a Haskell을 보셨습니까? 구문과 핵심 아이디어를 배우는 데 도움이되는 언어에 대한 매우 온화하고 재미있는 소개입니다.

+0

bheklir, 너를 존경하지만. 당신은 내가 빨기라도하는 것을 열망하는 haskeller의 유형입니다. 나는 한 번 봐서 하스켈을 배웠다.올바른 방향으로 'let'에 대한 문법적으로 올바른 정의를 가리켜 주셔서 감사합니다. 나는 아직도 따라 잡아야 할 것이 많고 왜 나는 "그것을 얻지 못하고"있는지 모른다. 슬프지만 이것이 풀 타임 포커스가 될 수는 없습니다. BC 저는 직업을 찾고 있습니다. 다시 한번 감사드립니다. – dgomez1092

+0

@ dgomez1092 처음 6 년 전 하스켈을 보았습니다. 나는 잠시 동안 언어를 터뜨렸지 만, 대부분의 대학에서는 그 언어를 사용하지 않았습니다. 인턴 과정에서 느린 기간을 보냈을 때 돌아 왔습니다. 몇 달 동안 많은 것을 두들기고 마침내 나는 그것을 얻었다고 생각했다. 몇 년 후 지금도 나는 그것을 끝내고 있는지 잘 모르겠다. 하스켈은 많은 사람들에게 이상하고 어려운 언어이지만, 그것을 지킬 가치가 있습니다! 당신이 빨아 먹는 것이 아니라, 더 많은 연습이 필요하다는 것입니다. 계속 질문을하고 연습을 계속하면 조각들이 떨어지기 시작할 것입니다. – bheklilr

1

귀하의 구문 분석 오류는 let 키워드에 있습니다. 그것을 제거하면 오류가 발생하지 않습니다. let x = y은 GHCi 및 do- 블록에만 관련 있으며이 시점에는 관련성이 없습니다. 기본적으로, 바로이 라인으로 교체 :

theWordIGet = stutter 6 "Iwannabehere" 

둘째, 하스켈 instance 키워드는이 단계에서 수행 할 작업을 함께 할 수있는 absolutley 아무것도이 없습니다. 이것은 하스켈 함수가 정의 된 방식이 아닙니다. 여러분이하고 싶은 것입니다. 이것은 문자열 n 번을 단순히 반복한다고 가정하고 stutter 함수를 만들기 위해 수행하고자하는 작업입니다.

stutter :: Int -> String -> String 
stutter n x = concat (replicate n x) 

또한에 대한 형식 선언을 제거 할거야 (범위 밖) nx 값 : 그들은 아니에요 자신의 서명이 함수에 대한 객체들이있는 거 인수 함수 호출 내에서 nx의 유형을 결정합니다.

마지막으로 프로그램이 실행될 때 stutter 6 "Iwannabehere"의 값을 인쇄하려고합니다. 이를 위해, 그냥이 추가 :

main :: IO() 
main = print (stutter 6 "Iwannabehere") 

은 결론적으로, 내가를 간청 처음부터 시작하고 읽고 온라인 '당신을 알아 하스켈'here, 당신은 완전히 잘못된 방향으로 떨어져거야 때문에 - 당신이 인용 한 프로그램은 일 수있는 표현의 뒤죽박죽이지만 의미가 있지만 완전히 잘못된 장소에 있습니다. 이 책은 Haskell의 구문을 훨씬 잘 보여 주며이 답변에서 내가 쓸 수있는 내용을 설명하고 예상대로 프로그램을 동작시키는 방법을 완전히 설명합니다.