haskell gadt arrows

haskell - ¿Mensaje de error extraño, "Mi cerebro acaba de explotar"?



gadt arrows (1)

Considera el GADT

data S a where S :: Show a => S a

y la ejecución del código.

foo :: S a -> a -> String foo s x = case s of S -> show x

En una implementación de Haskell basada en un diccionario, uno esperaría que el valor s tenga un diccionario de clase, y que el case extraiga la función show de dicho diccionario para que se pueda show x .

Si ejecutamos

foo undefined (/x::Int -> 4::Int)

obtenemos una excepción Operativamente, esto se espera, porque no podemos acceder al diccionario. Más en general, el case (undefined :: T) of K -> ... producirá un error porque obliga a la evaluación de undefined (siempre que T no sea un tipo newtype ).

Considere ahora el código (vamos a pretender que esto se compila)

bar :: S a -> a -> String bar s x = let S = s in show x

y la ejecución de

bar undefined (/x::Int -> 4::Int)

¿Qué debería hacer esto? Se podría argumentar que debería generar la misma excepción que con foo . Si este fuera el caso, la transparencia referencial implicaría que

let S = undefined :: S (Int->Int) in show (/x::Int -> 4::Int)

falla también con la misma excepción. Esto significaría que let está evaluando la expresión undefined , a diferencia de, por ejemplo,

let [] = undefined :: [Int] in 5

el cual se evalúa a 5 .

De hecho, los patrones en un let son flojos : no obligan a la evaluación de la expresión, a diferencia del case . Por eso, por ejemplo,

let (x,y) = undefined :: (Int,Char) in 5

Evalúa con éxito a 5 .

Uno podría querer hacer let S = e in e'' evalúe e si se necesita un show en e'' , pero se siente bastante raro. Además, al evaluar let S = e1 ; S = e2 in show ... let S = e1 ; S = e2 in show ... no estaría claro si evaluar e1 , e2 o ambos.

Por el momento, GHC elige prohibir todos estos casos con una regla simple: no hay patrones perezosos al eliminar un GADT.

Cuando trato de un patrón de GADT en una sintaxis de proc (con Netwire y Vinyl):

sceneRoot = proc inputs -> do let (Identity camera :& Identity children) = inputs returnA -< (<*>) (map (rGet draw) children) . pure

Recibo el error del compilador (bastante extraño), de ghc-7.6.3

My brain just exploded I can''t handle pattern bindings for existential or GADT data constructors. Instead, use a case-expression, or do-notation, to unpack the constructor. In the pattern: Identity cam :& Identity childs

Recibo un error similar cuando coloco el patrón en el patrón proc (...) . ¿Por qué es esto? ¿Es defectuoso, o simplemente no implementado?