haskell - ¿Por qué `print<$>(print“ hello ”)` print “hello”?
(1)
main :: IO (IO ())
main = print <$> (print "Hello, World!")
es equivalente, gracias a las leyes de mónada, a
main :: IO (IO ())
main = do
result <- print "Hello, World!"
return (print result)
Ahora,
print
siempre devuelve
()
como resultado, por lo que todo el código es equivalente a
main :: IO (IO ())
main = do
_ <- print "Hello, World!"
return (print ())
Finalmente, el resultado de
main
simplemente se descarta.
Es decir, la última línea podría ser
return (putStrLn "this is ignored")
y tener el mismo efecto.
Por lo tanto, el código solo ejecutará la primera
print "Hello, World!"
.
Yo recomendaría que siempre defina
main :: IO ()
.
Haskell nos permite declarar
main :: IO AnyTypeHere
, pero esto es (IMO) confuso.
También recomendaría que use
putStrLn
, y no
print
para imprimir cadenas, ya que este último citará y escapará de toda la cadena.
Al calcular
IO (IO ())
, se calculan tanto
(IO ())
como
()
, entonces, ¿por qué?
main :: IO (IO ())
main = print <$> (print "Hello, World!")
impresión
"Hello, World!"
no
IO "Hello, World!" -- ??
"Hello, World!"