haskell types combinators type-level-computation

haskell - ¿Hay "combinadores de nivel de tipo"? ¿Existirán en algún futuro?



types combinators (3)

Estoy escribiendo la respuesta aquí solo para aclarar cosas y para contar sobre los logros en los últimos años. Hay muchas funciones en Haskell y ahora puede escribir algunos operadores en tipo. Usando $ puedes escribir algo como esto:

foo :: Int -> Either String $ Maybe $ Maybe Int

para evitar paréntesis en lugar de buenos viejos

foo :: Int -> Either String (Maybe (Maybe Int))

Gran parte de lo que hace que el uso de haskell sea realmente agradable en mi opinión son combinadores como (.) , flip , $ <*> y etc. Parece que puedo crear una nueva sintaxis cuando lo necesito.

Hace algún tiempo, estaba haciendo algo en el que sería tremendamente conveniente si pudiera "voltear" un constructor de tipos. Supongamos que tengo algún tipo de constructor:

m :: * -> * -> *

y que tengo una clase MyClass que necesita un tipo con un constructor de tipos con kind * -> * . Naturalmente, elegiría codificar el tipo de forma que pueda hacerlo:

instance MyClass (m a)

Pero supongamos que no puedo cambiar ese código, y supongo que lo que realmente encaja en MyClass es algo como

type w b = m b a instance MyClass w where ...

y luego tendría que activar XTypeSynonymInstances . ¿Hay alguna manera de crear un Flip "tipo de combinador de tipo" de tal manera que yo solo pueda hacer:

instance MyClass (Flip m a) where ...

?? ¿O otras generalizaciones de nivel de tipo de operadores comunes que usamos en haskell? ¿Esto es útil o estoy divagando?

Editar:

Yo podría hacer algo como:

newtype Flip m a b = Flip (m b a) newtype Dot m w a = Dot m (w a) ...

Pero luego tendría que usar los constructores de datos Flip , Dot , ... para la comparación de patrones, etc. ¿Vale la pena?


Puede hacer lo siguiente, pero no creo que sea realmente útil, ya que todavía no puede aplicarlo parcialmente:

{-# LANGUAGE TypeFamilies, FlexibleInstances #-} module Main where class TFlip a where type FlipT a instance TFlip (f a b) where type FlipT (f a b) = f b a -- *Main> :t (undefined :: FlipT (Either String Int)) -- (undefined :: FlipT (Either String Int)) :: Either Int [Char]

También vea esta discusión anterior: ¿ Lambda para expresiones tipográficas en Haskell?


Su pregunta tiene sentido, pero la respuesta es: no, actualmente no es posible.

El problema es que (en el sistema de tipos de Haskell de GHC) no puedes tener lambdas en el nivel de tipo. Para cualquier cosa que intente que parezca que podría emular o lograr el efecto de un lambda de nivel de tipo, descubrirá que no funciona. (Lo sé, porque lo hice).

Lo que puedes hacer es declarar tus nuevos tipos de Flip y luego escribir las instancias de las clases que quieres para ellos, con mucho envoltorio y desenvolvimiento (por cierto: usar sintaxis de registro), y luego los clientes de las clases pueden usar los newtypes en Escriba firmas y no tenga que preocuparse por los detalles.

No soy un teórico del tipo y no sé los detalles de por qué no podemos tener lambdas de nivel de tipo. Creo que fue algo que ver con la inferencia de tipos que se vuelve imposible, pero una vez más, no lo sé.