getLine 함수를 사용하십시오.IO a -> a에서 함수를 작성 하시겠습니까?
은 내가이 IO 값에서 문자열을 추출하려면 어떻게 유형
getLine :: IO String
있습니다. 더 일반적으로 어떻게 변환합니까? 이것에
IO a
:
a
이 불가능합니다. 내가 왜 이럴 수 없어?
getLine 함수를 사용하십시오.IO a -> a에서 함수를 작성 하시겠습니까?
은 내가이 IO 값에서 문자열을 추출하려면 어떻게 유형
getLine :: IO String
있습니다. 더 일반적으로 어떻게 변환합니까? 이것에
IO a
:
a
이 불가능합니다. 내가 왜 이럴 수 없어?
하스켈의 경우 IO
에 "트랩 된"값을 사용하려면 IO
값을 사용하지 마십시오. 대신 수행 할 작업을 IO
에 넣으십시오!
예를 들어, length
Prelude의 기능을 사용하여 getLine :: IO String
이 생성 할 문자 수를 확인한다고 가정합니다.
가, IO
에 전문 때, 종류가 fmap
라는 도우미 함수가 존재 : 그것은 IO
에 갇혀 "순수"값에서 작동하는 기능을한다
fmap :: (a -> b) -> IO a -> IO b
, 당신에게 기능을 제공합니다 IO
에 갇혀있는 값과 함께 작동합니다. 이 코드
fmap length getLine :: IO Int
콘솔에서 라인을 읽는 IO
행동을 나타낸다는 것을 의미하고 당신에게 길이를 제공합니다.
<$>
은 더 단순하게 만들 수있는 fmap
의 중위 동의어입니다. 이것은 위의 코드에 해당 : 이제
length <$> getLine
, 당신은 IO
-trapped 값을 반환IO
-trapped 값 자체 수행 할 때때로 동작을 제어한다. 간단한 예 : 방금 읽은 문자열을 putStrLn :: String -> IO()
을 사용하여 다시 쓸 수 있습니다.
이 경우 fmap
은 충분하지 않습니다. IO
으로 전문화 된 (>>=)
연산자는 IO a -> (a -> IO b) -> IO b
유형이어야합니다. 아웃 경우 :
getLine >>= putStrLn :: IO()
체인에 IO
작업을 (>>=)
를 사용하는 것은 필수적 순차적 맛이있다. 이보다 자연적인 방법으로 이와 같은 순차적 인 쓰기 작업을하는 데 도움이 "do-notation"라는 문법 설탕의 종류 :
do line <- getLine
putStrLn line
공지 사항을 여기에 <-
이 연산자 아니라고는하지만, 문법 설탕의 일부가 할 일에 의해 제공 표기법.
이 일반적인 질문에 대한 간단한 설명! "대신에 수행하려는 작업을 IO에 넣어야합니다." – luqui
C를 알고 있다면 "gets
에서 문자열을 가져올 수 있습니까?"라는 질문을 고려하십시오. IO String
은 얻기가 힘들어하는 문자열이 아니며, 네트워크 또는 표준 입력에서와 같이 문자열을 반환 할 수있는 프로 시저입니다. 을 실행하려면 문자열을 가져 오는 절차를 실행하십시오. 당신 위는 다음 String
값을 얻을 수 있지만 원하는 값을 사용하도록 getLine
작업을 실행에
main = do
someString <- getLine
-- someString :: String
print someString
: 순서대로 IO 작업을 실행하는
일반적인 방법은 do
표기법입니다.
do
블록에있는 사람이라면 <-
으로 (비공식적으로/부정확하게) IO에서 값을 가져올 수 있습니다. 예를 들어
는 다음과 같은 기능을 getLine
에서 선을 소요, 단지 문자열
main = do
line <- getLine
putStrLn (wrap line)
wrap :: String -> String
wrap line = "'" ++ line ++ "'"
당신이 wrap
으로이 컴파일하는 경우, 명령 줄 실행에 소요 순수 함수에 전달
echo "Hello" | wrap
당신이 볼 수
'Hello'
"일반적으로"그래서이 유형의 함수가 필요한 이유는 분명치 않으며이 경우에는 모든 점에서 차이가 있습니다.
가능한 것은 완전해야 함을 유의해야합니다. 실제로 unsafePerformIO
이라는 기본 라이브러리에 IO a -> a
유형의 기능이 있습니다.
그러나 unsafe
부분이 이유가 있습니다. 그 사용이 정당하다고 여겨지는 경우는 거의 없습니다. 대단히 조심스럽게 사용되는 탈출구입니다. 대부분의 경우 자신을 버리는 대신에 괴물을 들게합니다.
왜 일반적으로 IO a
에서 a
으로 갈 수 없습니까? 적어도 순전히 전혀 순수하지 않은 겉으로보기에 순수한 함수를 가짐으로써 규칙을 깨뜨릴 수 있습니다. 이 작업을 수행하는 것이 일반적인 관행 인 경우 유형 서명 및 컴파일러에서 검증 한 모든 작업이 전혀 의미가 없습니다. 모든 정확성 보장은 창 밖으로 나옵니다.
하스켈은 (일반적으로) 불가능하기 때문에 부분적으로 흥미 롭습니다.
특히 getLine
문제에 대한 접근 방법은 다른 답변을 참조하십시오.
이렇게 할 수 있다면 처음에는 IO 유형을 사용하지 않아도됩니다. – sepp2k
중복 될 수 : [* 어떻게하면 하스켈에서 IO 문자열을 구문 분석 할 수 있습니까?] (http://stackoverflow.com/q/11229854/2751851) 중복 대상). – duplode