Try {-# LANGUAGE NoMonomorphismRestriction #-}
http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/monomorphism.html
Вопрос
I have a function with a following type signature
{-# LANGUAGE FlexibleContexts #-}
dataLat :: Load r DIM1 Double
=> (Array r DIM1 Double -> Array U DIM1 Double, Array U DIM1 Double)
Array
, U
and DIM1
come from Repa library. dataLat
creates data that is later passed to other functions as a tuple. At one point r
type variable gets unified with type D
(this is again from Repa), but at later point r
should also unify with type L
(this is my type). The problem is that it has already been unified with D
and cannot be therefore unified with L
. I end up with Couldn't match expected type
error. I think this should be solved by some form of higher rank types, but I am unable to figure out how this should be written. Can anyone give me a hand?
Решение
Try {-# LANGUAGE NoMonomorphismRestriction #-}
http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/monomorphism.html
Другие советы
You can give dataLat
a type saying that it returns a polymorphic function, using Rank2Types
.
newtype Unboxer =
Unboxer {applyUnboxer :: forall repr. Load repr DIM1 Double => Array repr DIM1 Double -> Array U DIM1 Double}
dataLat :: (Unboxer, Array U DIM1 Double)
The body of dataLat
must put a polymorphic function into Unboxer
. The field accessor, applyUnboxer
, returns a polymorphic function that can be used at different types.
It's not clear to me that you really need rank-2 types. Since dataLat
takes no arguments, you can probably define the unboxer as a global function with ordinary rank-1 polymorphism.
To be precise, it doesn't make sense to unify a type variable with multiple types. To unify r
with U
and D
would amount to saying that r == U
and U == D
, which is false. The code above allows a function to be instantiated to multiple types. Think of instantiation as making a copy of the code before assigning types, so you have one instance of the function where r₁ == U
and a separate instance where r₂ == D
.