esto no funciona, pero pensé que era lo suficientemente interesante para compartir todos modos:
{-#LANGUAGE GADTs #-}
data Poly a where
Poly :: [b] -> Poly [b]
Ahora tenemos una poli tipo que está parametrizado en a
, pero con eficacia a
tiene que ser una lista:
~% ghci Poly.hs
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
[1 of 1] Compiling Main (Poly.hs, interpreted)
Ok, modules loaded: Main.
*Main> :k Poly
Poly :: * -> *
*Main> :t Poly
Poly :: [b] -> Poly [b]
*Main> case Poly [1,2,3] of _ -> 0
0
*Main> case Poly 4 of _ -> 0
<interactive>:1:10:
No instance for (Num [b])
arising from the literal `4' at <interactive>:1:10
Possible fix: add an instance declaration for (Num [b])
In the first argument of `Poly', namely `4'
In the scrutinee of a case expression: Poly 4
In the expression: case Poly 4 of _ -> 0
*Main> case Poly True of _ -> 0
<interactive>:1:10:
Couldn't match expected type `[b]' against inferred type `Bool'
In the first argument of `Poly', namely `True'
In the scrutinee of a case expression: Poly True
In the expression: case Poly True of _ -> 0
Ahora podemos tratar de escribir una instancia de Functor
para este tipo:
instance Functor Poly where
fmap f (Poly x) = Poly (f x)
Couldn't match expected type `[b1]' against inferred type `b2'
`b2' is a rigid type variable bound by
the type signature for `fmap' at <no location info>
In the first argument of `Poly', namely `(f x)'
In the expression: Poly (f x)
In the definition of `fmap': fmap f (Poly x) = Poly (f x)
Eso no va a funcionar. Curiosamente, ni siquiera podemos escribir realmente myMap
:
polymap f (Poly x) = Poly (f x)
Si tratamos esto obtenemos
GADT pattern match in non-rigid context for `Poly'
Tell GHC HQ if you'd like this to unify the context
In the pattern: Poly x
In the definition of `polymap': polymap f (Poly x) = Poly (f x)
Por supuesto que podemos fijarlo con una anotación de tipo:
polymap :: ([a] -> [b]) -> Poly [a] -> Poly [b]
Pero sin eso, es un problema similar al que tenía fmap. Functor simplemente no tiene ningún lugar para salir de este contexto adicional de "Prometo siempre usar listas", y de hecho no puede. Siempre puede decir undefined :: Poly Int
por ejemplo. En resumen, no creo que realmente haya una expresión idiomática que pueda expresar esto (en realidad, alguien probablemente vendrá con suficiente magia de extensión ghc para hacerlo). Ciertamente no es uno existente.
¿Qué le gustaría que hiciera 'fmap (take 3) polynomial'? No tiene sentido para mí en absoluto. - 'polynomial' es simplemente un polinomio' polynomial :: Poly CoeffType' '= Poly [a₁, a₂ ..]'? – leftaroundabout
@leftaroundabout: He dado un código de ejemplo. – Xodarap
Como esto no es realmente una operación canónica (cómo debería saber la clase de fuente que es una lista y no una matriz, por ejemplo), no la convertiría en ninguna instancia. Tampoco lo llamaría "some-'map'" sino más bien 'coeffsTransform' o algo así. – leftaroundabout