Higher kinded datatypes allow for much easier processing of similar types, as shown here:
https://chrispenner.ca/posts/hkd-options
It would be nice to be able to have Generic instance of Interpret that reads any higher kinded type.
The difference seems simple on the surface. Instead of:
data MyConfig = MyConfig {
port :: Int
, host :: String
}
We use:
data MyConfig f = MyConfig {
port :: f Int
, host :: f String
}
Reading a plain data structure instead of this type:
interpret :: Type MyConfig -> Text -> IO MyConfig
gets this type:
interpret :: Type (MyConfig Identity) -> Text -> IO (MyConfig Identity)
If we want to use interpret to read Dhall with arbitrary annotation attached to datatype (#1148), that gets tugged-along, then we get:
data Annotated a = Annotated { ann:: Annotation, content :: a }
interpret :: Type (MyConfig Annotated) -> Text -> IO (MyConfig Annotated)
This is possible without any changes to the Haskell API if you use GHC version 8.6 or later (which provides the QuantifiedConstraints extension).
Here is a slightly modified version of the example you gave:
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
import Dhall (Generic, Interpret(..), Natural)
import Data.Functor.Identity (Identity(..))
import qualified Data.Coerce
import qualified Dhall
data MyConfig f = MyConfig
{ port :: f Natural
, host :: f String
} deriving (Generic)
instance Interpret a => Interpret (Identity a) where
autoWith = Data.Coerce.coerce (autoWith @a)
instance (forall a . Interpret a => Interpret (f a)) => Interpret (MyConfig f)
data Annotated a = Annotated { ann :: String, content :: a }
deriving (Generic, Interpret)
main :: IO ()
main = do
x <- Dhall.input Dhall.auto "{ port = 80, host = \"example.com\" }"
print (runIdentity (port x))
y <- Dhall.input Dhall.auto "{ port = { ann = \"Hi!\", content = 80 }, host = { ann = \"Bye!\", content = \"example.com\" } }"
print (ann (host y))
... which produces this output:
"Bye!"
Thanks @Gabriel439. Will be happy to use it!
@mgajda: You're welcome! 馃檪
Most helpful comment
This is possible without any changes to the Haskell API if you use GHC version 8.6 or later (which provides the
QuantifiedConstraintsextension).Here is a slightly modified version of the example you gave:
... which produces this output: