Open debasishg opened 5 years ago
Oh! Yeah, there's no way for GHC to know that load
is referring to the i
type variable, and that save
is for the o
type variable.
To fix this, we need to enable ScopedTypeVariables
and TypeApplications
and do:
migrate :: forall i o. (LoadData i, SaveData o, ConvertData i o) => IO ()
migrate = do
old <- load @i
save (map convert old)
That should fix the issue.
Thanks Matt. Maybe we need some other extension as well .. Now it errors at @i
of load
-
Not in scope: type variable ‘i’
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Migratedb where
class LoadData i where
load :: IO [i]
class SaveData o where
save :: [o] -> IO ()
class ConvertData i o | i -> o where
convert :: i -> o
migrate :: (forall i o. (LoadData i, SaveData o, ConvertData i o)) => IO ()
migrate = do
old <- load @i
save (map convert old)
You have an extra set of parentheses - (forall i o. (...)) => IO ()
is different from forall i o. (...) => IO ()
.
Even with this ..
migrate :: forall i o. (LoadData i, SaveData o, ConvertData i o) => IO ()
migrate = do
old <- load @i
save (map convert old)
I get the same error ..
/Users/debasishghosh/projects/hs/learn-haskell/src/LearnBasic1.hs:81:16: error:
Not in scope: type variable ‘i’
|
81 | old <- load @i
| ^
Here's a full module that compiles:
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Migratedb where
class LoadData i where
load :: IO [i]
class SaveData o where
save :: [o] -> IO ()
class ConvertData i o | i -> o where
convert :: i -> o
migrate :: forall i o. (LoadData i, SaveData o, ConvertData i o) => IO ()
migrate = do
old <- load @i
save (map convert old)
We need AllowAmbiguousTypes
because the type IO ()
doesn't refer to all of the type variables.
ah .. that does it .. Thanks a lot Matt ..
With AllowAmbiguousTypes
it compiles, but when I try to run migrate
, I get the following ..
Ambiguous type variable ‘i0’ arising from a use of ‘migrate’
prevents the constraint ‘(LoadData i0)’ from being solved.
Probable fix: use a type annotation to specify what ‘i0’ should be.
These potential instance exist:
instance LoadData Old
-- Defined at /private/var/folders/th/mq68kp9533z31prp3x7fm7rw0000gn/T/ghc-mod11862/EffectsOnTheEdge11861-0.hs:44:10
• In the expression: migrate
In an equation for ‘main’: main = migrate
Do we need to use equality constraints in typeclass instance with TypeFamilies
extensions as in https://chrisdone.com/posts/haskell-constraint-trick/ ?
Thanks.
Good stuff reading the post. I was trying to compile this ..
and got the following compiler error with the
migrate
function ..I have
{-# LANGUAGE FunctionalDependencies #-}
applied.Thanks.