Pregunta

Disculpas por adelantado si esta pregunta es un poco vago. Es el resultado de una ensoñación fin de semana.

Con sistema de tipos de Haskell maravillosa, es deliciosamente agradable a expresar estructura matemática (especialmente algebraica) como clases de tipos. Es decir, sólo echar un vistazo a numérico-preludio ! Pero tomar ventaja de tal estructura de tipo maravilloso en la práctica siempre ha parecido difícil para mí.

Tiene una buena manera, el tipo de sistema de expresar que v1 y v2 son elementos de un espacio vectorial V y que w es un elemento de un espacio vectorial W. El sistema de tipos le permite escribir un programa añadiendo v1 y v2, pero no v1 y w. ¡Excelente! Pero en la práctica es posible que desee jugar con potencialmente cientos de espacios vectoriales, y desde luego no querer crear tipos V1, V2, ..., V100 lo cuenten las instancias de la clase de tipos de vector espacial! O tal vez de leer algunos datos del mundo real que resulta en símbolos a, b y c - es posible que desee expresar que el espacio vectorial libre sobre estos símbolos es realmente un espacio vectorial

Así que usted está atascado, ¿verdad? Con el fin de hacer muchas de las cosas que le gustaría hacer con los espacios vectoriales en un entorno de computación científica, tiene que renunciar a su sistema de tipos por lo que dejaría un espacio vectorial clase de tipos y funciones que tiene hacer pruebas de compatibilidad en tiempo de ejecución en su lugar. Si se tiene que? ¿No debería ser posible utilizar el hecho de que Haskell es puramente funcional para escribir un programa que genera todos los tipos que necesita e insertos ellos en el programa real? EXISTE TAL una técnica? Por todos los medios no señalan si simplemente estoy pasando por alto algo básica aquí (probablemente soy): -)

Editar Ahora mismo me descubro FUNDEPS . Voy a tener que pensar un poco acerca de cómo se relacionan con mi pregunta (que alumbra los comentarios con respecto a este se aprecia).

¿Fue útil?

Solución

Plantilla Haskell permite que este . El href="http://www.haskell.org/haskellwiki/Template_Haskell" rel="nofollow"> página tiene algunos enlaces útiles; particularmente de Bulat tutoriales .

La sintaxis de declaración de nivel superior es el que usted desea. Escribiendo:

mkFoo = [d| data Foo = Foo Int |]

se genera una plantilla de empalme Haskell (como una función de tiempo de compilación) que va a crear una declaración de data Foo = Foo Int simplemente insertando el $(mkFoo) línea.

Si bien este pequeño ejemplo no es demasiado útil, que podría proporcionar un argumento para mkFoo para controlar el número de declaraciones diferentes que desee. Ahora, un $(mkFoo 100) producirá 100 nuevas declaraciones de datos para usted. También puede utilizar TH para generar instancias de la clase de tipo. Mi paquete adaptativo-tupla es un proyecto muy pequeño que utiliza la plantilla Haskell hacer algo similar.

Un enfoque alternativo sería el uso de Derivar , que examinará instancias de la clase de tipo automáticamente Derivar . Esto podría ser más simple si sólo necesita los casos.

Otros consejos

También hay algunas técnicas de programación a nivel de tipo simple en Haskell. Un ejemplo canónico sigue:

-- A family of types for the natural numbers
data Zero
data Succ n

-- A family of vectors parameterized over the naturals (using GADTs extension)
data Vector :: * -> * -> * where
    -- empty is a vector with length zero
    Empty :: Vector Zero a
    -- given a vector of length n and an a, produce a vector of length n+1
    Cons  :: a -> Vector n a -> Vector (Succ n) a

-- A type-level adder for natural numbers (using TypeFamilies extension)
type family Plus n m :: *
type instance Plus Zero n = n
type instance Plus (Succ m) n = Succ (Plus m n)

-- Typesafe concatenation of vectors:
concatV :: Vector n a -> Vector m a -> Vector (Plus n m) a
concatV Empty ys = ys
concatV (Cons x xs) ys = Cons x (concatV xs ys)

Tome un momento para tomar esa. Creo que es bastante mágico que funciona.

Sin embargo, la programación a nivel de tipo de Haskell está en la característica extraña-valle - lo suficiente como para llamar la atención sobre la cantidad que no se puede hacer. lenguajes de tipo dependientemente-como Agda , Coq y Epigram llevar este estilo a su límite y toda la potencia.

Plantilla Haskell es mucho más parecido al estilo habitual LISP-macro de generación de código. Se escribe algo de código para escribir un código, entonces se dice "ok inserción que genera código aquí". A diferencia de la técnica anterior, se puede escribir ningún código computablemente especificado por ese camino, pero no obtener la verificación de tipos muy general como se ve en concatV anteriormente.

Así que hay algunas opciones para hacer lo que quiera. Creo metaprogramming es un espacio muy interesante, y en cierto modo todavía muy joven. Divertirse explorando. : -)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top