read putstrln inputs haskell io monads readfile

inputs - putstrln haskell



Una funciĆ³n de tipo Haskell: IO String-> String (4)

Bueno, no puedes deshacerte de la parte de IO String de IO String . Eso significa que tendrá que hacer que su función devuelva IO [(String, [Integer])] .

Recomiendo aprender más sobre las mónadas, pero por ahora puedes salirte con la función liftM :

liftM index (readFile "input.txt")

liftM tiene esta firma:

liftM :: Monad m => (a -> b) -> m a -> m b

Toma una función no monádica y la transforma en una función monádica.

Escribí un montón de código en Haskell para crear un índice de un texto. La función superior se ve así:

index :: String -> [(String, [Integer])] index a = [...]

Ahora quiero darle a esta función una lectura de cadena de un archivo:

index readFile "input.txt"

Lo cual no funcionará porque readFile es de tipo FilePath -> IO String.

No se pudo hacer coincidir el tipo esperado ''Cadena'' con el tipo inferido ''Cadena IO''

Veo el error, pero no puedo encontrar ninguna función con el tipo:

IO String -> String

Supongo que la clave del éxito está en algún lugar debajo de algunas Mónadas, pero no pude encontrar una manera de resolver mi problema.


Hay una muy buena razón por la cual no existe tal función.

Haskell tiene la noción de pureza funcional. Esto significa que una función siempre devolverá el mismo resultado cuando se invoque con los mismos parámetros. El único lugar donde se permite IO es dentro de la mónada IO.

Si había * una función

index :: IO String -> String

entonces podríamos hacer acciones IO repentinamente en cualquier lugar llamando, por ejemplo:

index (launchMissiles >> deleteRoot >> return "PWNd!")

La pureza funcional es una característica muy útil que no queremos perder, ya que permite al compilador reordenar y alinear funciones mucho más libremente, se pueden activar en diferentes núcleos sin cambiar la semántica y también les da a los programadores un sentido de seguridad, ya que si puede saber qué función puede y qué no puede hacer su tipo.

* En realidad hay tal función. Se llama unsafePerformIO y se llama así por muy, muy buenas razones. ¡No lo use a menos que esté 100% seguro de lo que está haciendo!


Puede escribir fácilmente una función que llame a la acción readFile y pasa el resultado a su función de índice.

readAndIndex fileName = do text <- readFile fileName return $ index text

Sin embargo, la mónada IO contamina todo lo que la usa, por lo que esta función tiene el tipo:

readAndIndex :: FilePath -> IO [(String, [Integer])]


fmap index $ readFile "input.txt"

o

readFile "input.txt" >>= return . index

Es posible que desee buscar en mónada y functors