scala haskell scalaz

scala - Girando A=> M[B] en M



haskell scalaz (3)

En la práctica

No, no se puede hacer, al menos no de una manera significativa.

Considera este código de Haskell

action :: Int -> IO String action n = print n >> getLine

Esto toma n primero, lo imprime (IO realizado aquí), luego lee una línea del usuario.

Supongamos que tenemos una transform :: (a -> IO b) -> IO (a -> b) hipotética transform :: (a -> IO b) -> IO (a -> b) . Luego, como un experimento mental, considere:

action'' :: IO (Int -> String) action'' = transform action

Lo anterior tiene que hacer todo el IO por adelantado, antes de saber n , y luego devolver una función pura. Esto no puede ser equivalente al código anterior.

Para enfatizar el punto, considere este código sin sentido a continuación:

test :: IO () test = do f <- action'' putStr "enter n" n <- readLn putStrLn (f n)

Mágicamente, la action'' debe saber de antemano lo que el usuario va a escribir a continuación". Una sesión se vería como

42 (printed by action'') hello (typed by the user when getLine runs) enter n 42 (typed by the user when readLn runs) hello (printed by test)

Esto requiere una máquina del tiempo, por lo que no se puede hacer.

En teoria

No, no se puede hacer. El argumento es similar al que yo di a una pregunta similar .

Supongamos por contradicción transform :: forall ma b. Monad m => (a -> mb) -> m (a -> b) transform :: forall ma b. Monad m => (a -> mb) -> m (a -> b) existe. Especialice m en la mónada de continuación ((_ -> r) -> r) (omito el envoltorio de tipo nuevo).

transform :: forall a b r. (a -> (b -> r) -> r) -> ((a -> b) -> r) -> r

Especializar r=a :

transform :: forall a b. (a -> (b -> a) -> a) -> ((a -> b) -> a) -> a

Aplicar:

transform const :: forall a b. ((a -> b) -> a) -> a

Por el isomorfismo de Curry-Howard, lo siguiente es una tautología intuicionista

((A -> B) -> A) -> A

pero esta es la Ley de Peirce, que no es demostrable en la lógica intuicionista. Contradicción.

Para una mónada M , ¿es posible convertir A => M[B] en M[A => B] ?

Intenté seguir los tipos en vano, lo que me hace pensar que no es posible, pero pensé que lo haría de todos modos. Además, buscar en Hoogle a -> mb -> m (a -> b) no devolvió nada, así que no tengo mucha suerte.


Las otras respuestas han ilustrado muy bien que, en general, no es posible implementar una función de a -> mb a m (a -> b) para cualquier mónada m . Sin embargo, hay mónadas específicas donde es bastante posible implementar esta función. Un ejemplo es la mónada del lector:

data Reader r a = R { unR :: r -> a } commute :: (a -> Reader r b) -> Reader r (a -> b) commute f = R $ /r a -> unR (f a) r


No.

Por ejemplo, Option es una mónada, pero la función (A => Option[B]) => Option[A => B] no tiene una implementación significativa:

def transform[A, B](a: A => Option[B]): Option[A => B] = ???

¿Qué pones en lugar de ??? ? ¿ Some ? Some de qué entonces? O None ?