2010-08-04 13 views
16

Como propuso Moggi hace 20 años, el espacio de función efectiva -> de idiomas como ML se puede descomponer en el espacio de función total estándar => más una mónada fuerte T para capturar efectos.¿Qué tan práctico es incorporar el núcleo de un lenguaje con un espacio funcional funcional (como ML) en Haskell?

A -> B descompone a A => (T B)

Ahora, Haskell apoya mónadas, incluyendo una mónada IO que aparece suficiente para los efectos en ML, y tiene un espacio de funciones que contiene => (pero también incluye funciones parciales). Entonces, deberíamos poder traducir un considerable fragmento de ML en Haskell a través de esta descomposición. En teoría, creo que esto funciona.

Mi pregunta es si una incrustación como esta puede ser práctica: ¿es posible diseñar una biblioteca Haskell que permita programar en Haskell con un estilo no muy lejano al de ML? Y si es así, ¿cómo será el rendimiento?

Mi criterio para "práctico" es que el código ML existente con uso extensivo de efectos podría transcribirse con relativa facilidad en Haskell a través de la incrustación, incluidos casos complicados que implican funciones de orden superior.

Para hacer esto concreto, mi intento de tal transcripción a través de la incrustación está a continuación. La función principal es una transcripción de algún código ML simple que imperativamente genera 5 nombres de variable distintos. En lugar de usar la descomposición directamente, mi versión levanta funciones para que evalúen sus argumentos: las definiciones anteriores a main son una mini biblioteca que incluye primitivas levantadas. Esto funciona bien, pero algunos aspectos no son totalmente satisfactorios.

  1. Hay demasiado ruido sintáctico para la inyección de valores en los cálculos a través de val. Tener versiones no actualizadas de funciones (como rdV) ayudaría a esto, a costa de que se definan.
  2. Definiciones sin valor como varNum requieren unión monadic a través de <- en un do. Esto obliga a que las definiciones que dependen de ellos también estén en la misma expresión do.
  3. Parece que todo el programa podría terminar en una gran expresión do. Así es como a menudo se consideran los programas de ML, pero en Haskell no es lo suficientemente compatible, por ejemplo, estás obligado a usar case en lugar de ecuaciones.
  4. Supongo que habrá algo de pereza a pesar de enhebrar la mónada de IO en todo. Dado que el programa de ML estaría diseñado para una evaluación estricta, la pereza probablemente debería eliminarse. No estoy seguro de cuál es la mejor manera de hacer esto.

lo tanto, cualquier asesoramiento para mejorar esto, o en mejores enfoques utilizando la misma descomposición, o incluso muy diferentes maneras de lograr el mismo objetivo general de la programación en Haskell usando un estilo que refleja ML? (No es que me gusta el estilo de Haskell, es sólo que me gustaría ser capaz de asignar el código de ML existente fácilmente.)

import Data.IORef 
import Control.Monad 

val :: Monad m => a -> m a 
val = return 

ref = join . liftM newIORef 
rdV = readIORef         -- Unlifted, hence takes a value 
(!=) r x = do { rr <- r; xx <- x; writeIORef rr xx } 

(.+),(.-) :: IO Int -> IO Int -> IO Int 
((.+),(.-)) = (liftM2(+), liftM2(-)) 

(.:) :: IO a -> IO [a] -> IO [a] 
(.:) = liftM2(:) 
showIO :: Show a => IO a -> IO String 
showIO = liftM show 

main = do 
    varNum <- ref (val 0) 
    let newVar = (=<<) $ \() -> val varNum != (rdV varNum .+ val 1) >> 
           val 'v' .: (showIO (rdV varNum)) 
    let gen = (=<<) $ \n -> case n of 0 -> return [] 
             nn -> (newVar $ val()) .: (gen (val n .- val 1)) 
    gen (val 5) 
+8

+1 por hacer una pregunta No soy lo suficientemente inteligente como para contribuir a – delnan

+0

Dada la naturaleza de las preguntas y respuestas que ha publicado, ¿consideraría? [Agregue su ayuda aquí] (http://area51.stackexchange.com/ propuestas/8766/theory-computer-science) si aún no lo has hecho? –

+2

@camccann Interesante - Supongo que he estado probando y descubriendo que Stack Overflow es útil para estas preguntas (con esta quizás superando los límites, o simplemente siendo difícil de responder). Estoy algo dividido en un sitio de TCS: generalmente no me gusta separar la teoría de la práctica, ni el término "teórico". Esta pregunta se relaciona con las mónadas, pero principalmente estoy preguntando sobre algo de uso práctico. Personalmente, podría estar más feliz con una etiqueta TCS en SO. En general, creo que agrupar las cosas y luego proyectar subconjuntos a través de etiquetas es un mejor modelo cuando no hay una línea divisoria clara. – RD1

Respuesta

3

Here 's una manera posible, por SIGFPE. No cubre lambdas, pero parece que se puede extender a ellos.

+0

Un par de técnicas interesantes que puedo intentar usar. Es una idea similar a la del código que di (no es sorprendente ya que Andrzej Filinski y yo estudiamos juntos en CMU). Además, clasifico esa incrustación en "obras en teoría" en lugar de "funciona en la práctica". Además, supongo que me gustaría evitar las plantillas por ahora y ver qué embeddings agradables son posibles sin hackear la sintaxis. – RD1

Cuestiones relacionadas