haskell types functional-programming ghc type-declaration

haskell - Cómo relacionarse con el tipo de contexto externo



types functional-programming (2)

Esto es posible con la extensión ScopedTypeVariables . Necesita usar reglas explícitas para poner las variables de tipo dentro del alcance.

blah :: forall a b. a -> b -> a blah x y = ble x where ble :: b -> b ble x = x

Intentar cargar esta definición con ScopedTypeVariables habilitado da:

foo.hs:2:16: Couldn''t match type `a'' with `b'' `a'' is a rigid type variable bound by the type signature for blah :: a -> b -> a at foo.hs:2:1 `b'' is a rigid type variable bound by the type signature for blah :: a -> b -> a at foo.hs:2:1 In the first argument of `ble'', namely `x'' In the expression: ble x In an equation for `blah'': blah x y = ble x where ble :: b -> b ble x = x

Puede decir que GHC interpreta las dos b s como del mismo tipo porque el error dice que a y b están vinculados en la misma línea.

Consideremos el siguiente fragmento de código:

blah :: a -> b -> a blah x y = ble x where ble :: b -> b ble x = x

Esto compila bien bajo GHC, lo que esencialmente significa que b de la 3ra línea es algo diferente de b de la primera línea.

Mi pregunta es simple: ¿hay alguna forma de relacionarse de algún modo en la declaración de tipo de ble con un tipo utilizado en un contexto externo, es decir, la declaración de tipo de blah ?

Obviamente, esto es solo un ejemplo y no un caso de uso del mundo real para las declaraciones de tipo.


Si no desea utilizar ScopedTypeVariables, puede utilizar la función good ole fashion asTypeOf .

-- defined in Prelude asTypeOf :: a -> a -> a x `asTypeOf` y = x

blah :: a -> b -> a blah x y = ble x where ble x = x `asTypeOf` y

Por supuesto, esto no se compilará debido al error de tipo.

Actualizar:

Me gustaría señalar que a veces puede ser un poco astuto hacer lo que quiera con asTypeOf . Tome el siguiente ejemplo que asTypeOf usa asTypeOf porque no quiero pensar en un caso que realmente necesite asTypeOf . Soluciones similares funcionarían igual para casos del mundo real.

foo :: Bounded a => Maybe a -> a foo m = x where x = maxBound -- Q: how do I make (x :: a) when given (Maybe a)? _ = Just x `asTypeof` m -- A: witchcraft!