I have a Haskell code that will not compile (with GHC 8.0.2). I think I understand the main problem, but I would like to understand it better in order to avoid this in the future.
My library looks something like this:
{-# language TypeFamilyDependencies #-}
{-# language GADTs #-}
{-# language RankNTypes #-}
module Lib where
type Key = Int
class Handle m where
type Connection m = c | c -> m
withConnection :: Connection m -> m a -> IO a
class (Handle m) => Data m where
getKeyVal :: Key -> m String
data SomeConn where
SomeConn :: (Data m) => Connection m -> SomeConn
useConnection :: SomeConn -> (forall m. Data m => m String) -> IO String
useConnection (SomeConn c) action = withConnection c action
The idea is what Data mconstitutes a class of monads, similar ReaderT (Connection m) IO. I hope to write common functions using methods of this type, and an instance of the exact method is determined by the type of connection enclosed in SomeConn(which is selected at runtime).
Now the following code
getKeyValWith :: SomeConn -> Key -> IO String
getKeyValWith c = (useConnection c). getKeyVal
gives me the GHC 8.0.2 error:
• Couldn't match type ‘m0 String’
with ‘forall (m :: * -> *). Data m => m String’
Expected type: m0 String -> IO String
Actual type: (forall (m :: * -> *). Data m => m String)
-> IO String
• In the first argument of ‘(.)’, namely ‘useConnection c’
In the expression: useConnection c . getKeyVal
In an equation for ‘getKeyValWith’:
getKeyValWith c = useConnection c . getKeyVal
Oddly enough, the following works just fine:
getKeyValWith c k = useConnection c (getKeyVal k)
Less unexpectedly, also:
getKeyValWith (SomeConn c) = withConnection c . getKeyVal
, GHC , ? , GHC , , ? , , , Haskell ( "/typeclass anti-pattern" ).
Edit:
, , getKeyVal :: Key -> (Data m => m String) . ( typechecks), . , , :t GHCI ( -XRankNTypes), Data m =>, . , , GHC . GHC ?