haskell higher-rank-types newtype

haskell - newtype con RankNTypes



higher-rank-types (2)

Si quiero declarar un newtype tal que el tipo de tipo del valor está restringido para tener una instancia para una clase de tipo, parece que puedo hacerlo con:

{-# LANGUAGE RankNTypes #-} newtype ShowBox = ShowBox (forall a. Show a => a)

GHC compila eso bien, pero cuando lo intento y uso ShowBox con

ShowBox "hello"

Me sale un error de compilación

<interactive>:1:18: Could not deduce (a ~ [Char]) from the context (Show a) bound by a type expected by the context: Show a => a at <interactive>:1:10-24 `a'' is a rigid type variable bound by a type expected by the context: Show a => a at <interactive>:1:10 In the first argument of `ShowBox'', namely `"hello"'' In the expression: ShowBox "hello" In an equation for `a'': a = ShowBox "hello"

¿Hay alguna manera de hacer que esto funcione?


Bueno, tu constructor de Show tiene este tipo:

Show :: (forall a. Show a => a) -> ShowBox

Está intentando aplicar esta función al tipo [Char] , que no es del tipo forall a. Show a => a forall a. Show a => a , porque a es una "variable de Skolem" que solo se puede unificar con otro tipo bajo reglas muy estrictas (que otros podrán explicar mejor que yo).

¿Está seguro de que lo siguiente no es lo que quiere ( data módulo vs. newtype )? ¿Por qué forall al forall dentro del constructor?

-- Show :: Show a => a -> ShowBox data ShowBox = forall a. Show a => Show a


Le está prometiendo al compilador que el valor que ponga dentro de un ShowBox tendrá el tipo para todos forall a. Show a => a forall a. Show a => a . Solo hay un valor posible con ese tipo, y es _|_ . Creo que probablemente quieras un tipo existencial, que parece bastante similar, pero significa algo muy diferente.

{-# LANGUAGE ExistentialQuantification #-} data ShowBox = forall a. Show a => ShowBox a

Esto debe hacerse con data , en lugar de newtype . La coincidencia de patrones en el constructor es lo que lleva la instancia de Show al ámbito, en este caso. Dado que los newtype no tienen representación en tiempo de ejecución, no tienen lugar para almacenar el testigo polimórfico que implica la cuantificación existencial.