[haskell] `print <$> (print“hello”)`가“hello”를 인쇄하는 이유는 무엇입니까?

계산할 때 IO (IO ())모두 (IO ())()계산하므로 이유

main :: IO (IO ())
main = print <$> (print "Hello, World!")

인쇄

"Hello, World!"

아니

IO "Hello, World!" -- ??
"Hello, World!"



답변

main :: IO (IO ())
main = print <$> (print "Hello, World!")

모나드 법칙 덕분에

main :: IO (IO ())
main = do
   result <- print "Hello, World!"
   return (print result)

이제 print항상 ()결과로 반환 되므로 전체 코드는

main :: IO (IO ())
main = do
   _ <- print "Hello, World!"
   return (print ())

마지막으로 결과 main는 단순히 폐기됩니다. 즉, 마지막 줄은 return (putStrLn "this is ignored")효과가 동일 할 수 있습니다 .

따라서 코드는 첫 번째 코드 만 실행합니다 print "Hello, World!".

항상 정의하는 것이 좋습니다 main :: IO (). Haskell은 우리가 선언 할 수있게 main :: IO AnyTypeHere하지만 이것은 (IMO) 혼동됩니다.

후자는 전체 문자열을 인용하고 이스케이프하므로 문자열을 인쇄 putStrLn하지 print말고을 사용하는 것이 좋습니다 .


답변