Can I pass a typeclass dictionary to a function explicitly? - haskell

Let’s say I have some typeclass:
data Foo = Foo deriving (Show)
class Monad m => MonadFoo m where
getFoo :: m Foo
Since GHC implements typeclasses via dictionary passing (uses of SPECIALIZE notwithstanding), it effectively transforms getFoo into something like the following under the hood:
data MonadFooDict m = MonadFooDict { getFoo :: m Foo }
...and it inserts an additional argument at the beginning of calls to getFoo that threads the dictionary around.
Sometimes, I might want to pick an instance dynamically, so passing a dictionary myself might be desirable. I can simulate this myself by creating an instance that will thread the dictionary around for me.
newtype DynamicMonadFoo a = DynamicMonadFoo
{ runFoo :: MonadFooDict DynamicMonadFoo -> a }
deriving ( Functor, Applicative, Monad
, MonadReader (MonadFooDict DynamicMonadFoo) )
instance MonadFoo DynamicMonadFoo where
getFoo = join $ asks _getFoo
Now, given some function with a MonadFoo constraint, I can use the runFoo function to pass it an explicit typeclass dictionary:
showCurrentFoo :: MonadFoo m => m String
showCurrentFoo = do
foo <- getFoo
return ("current foo: " ++ show foo)
ghci> runFoo showCurrentFoo MonadFooDict { _getFoo = return Foo }
"current foo: Foo"
This is really cool, but it seems like such a simple task that GHC might expose some sort of library to do this without all the boilerplate (and ideally in a way that would work more nicely with non-monadic typeclasses). Given that GHC has some “reflection-esque” capabilities like Data.Typeable, this doesn’t seem outside the realm of possibility, but I’m not sure if it actually exists in some form.
Do any existing built-ins or other libraries allow doing this more automatically?

There is an article on this at the School of Haskell:
Reflecting values to types and back
See the section towards the end entitled Dynamically constructing type-class instances and But what about manual dictionaries?

Related

Possible to generically remove function types from datatype, to allow deriveJSON?

I have several datatypes representing the state of an application. In various places in the datatype, I have embedded functions or monadic actions, eg.
data Foo = Foo Int (ActionM String)
data Bar = Bar Foo (Maybe Bar) (ActionM ())
I need to encode most of these datatypes as json so I can send it to the browser for display. Using deriveJSON (from the Aeson package) doesn't work because instances for ActionM can't be derived. However, I don't actually want those bits to be sent anyway. I currently have an approach which works but is basically copy-pasting the full set of datatypes and manually removing the embeded ActionM fields.
I (think I) need one of a couple of things. Either
a way to tell deriveJSON to just ignore fields that it can't figure out, and maybe parse them back into undefined. As far as I can tell this doesn't exist
a way to automatically generate a parallel set of datatypes with these fields removed. So I want to write something like
applyMagic Bar
and get back
data Foo' = Foo' Int
data Bar' = Bar' Foo' (Maybe Bar')
Is any of this possible, and how would I do it?
This is a simplistic solution, but couldn't you do something like
data Foo' = Foo' Int
type Foo = (ActionM String, Foo')
and simply obtain the second element of the tuple when you want to serialize?
Tuples are an instance of ComonadEnv, so you could also use functions like ask and extract.
Edit. Bar is a more complicated case because it is a recursive type. But it could be handled using the CofreeT comonad transformer:
import Data.Functor.Identity
import Data.Bifunctor (second)
import Control.Comonad -- from 'comonad'
import Control.Comonad.Hoist.Class
import Control.Comonad.Trans.Cofree -- from 'free'
-- Orphan ComonadHoist instance that will likely be added in future
-- versions of free
instance Functor f => ComonadHoist (CofreeT f) where
cohoist g = CofreeT . fmap (second (cohoist g)) . g . runCofreeT
type Bar = CofreeT Maybe ((,) (ActionM ())) Foo
type Bar' = Cofree Maybe Foo'
applyMagic :: Bar -> Bar'
applyMagic = cohoist (Identity . extract) . fmap extract
CofreeT Maybe ((,) (ActionM ())) Foo is a non-empty list of Foo values that have been annotated with ActionM () values.
Cofree Maybe Foo' is a non-empty list of Foo' values, without extra annotations (Cofree Maybe Foo is a synonym for CofreeT Maybe Identity Foo', where Identity works as the trivial comonad.).
To transform one into the other, applyMagic first uses fmap extract to transform all the Foos into Foo's, and then uses cohoist from ComonadHoist to remove the "annotation layer" underneath CofreeT.
In general, values with "extra context" can often be modeled with comonads.

How to create an interface for a stateful component where the state type is opaque?

-- InternalComponent.hs
data ComponentState = ComponentState ...
instance Default ComponentState where ...
componentFunction :: (MonadState InternalComponentState m) => a -> m a
-- Program.hs
data ProgramState = forall cs. ProgramState {
componentState :: cs,
...
}
newtype MyMonad a = MyMonad { runMyMonad :: StateT ProgramState IO a }
myFunction a = do
s <- get
let cs = componentState s
let (r, cs') = runState (componentFunction a) cs
put $ s { componentState = cs' }
return r
What I want is to be able to use the componentFunction inside of MyMonad (in myFunction, as presented in the example), without being particularly interested in the actual type of the state the component requires. Keeping the component state inside of my own state isn't a requirement, but that's as far as my ability to use state in Haskell goes.
This can really be viewed as an equivalent of an implementation of a stateful interface in another programming language: instantiation of the interface with some implementation provides default state value, and every function called through that interface can modify that state. In any point isn't the user presented with implementation details.
In case it's not clear, the above example fails because the implementation of myFunction can't prove that the record selector provides an appropriate type (because it's an existential); at least that's how I understand it.
You can parametrize ProgramState by the type of the component state(s), e.g. have
data ProgramState cs = ProgramState { componentState :: cs }
This would mean you'll also have to expose the ComponentState type from InternalComponent.hs, but not the constructors. This way you give the type checker something to play with, but don't expose any internals to the users of InternalComponent.
First, I'd suggest to read Combining multiple states in StateT, just to see other available options.
Since in the case of nested states we need to update values inside more complex objects, using lens can make life a lot easier (see also this tutorial). A value of type Lens' s a knows how to reach a particular value of type a inside s and how to modify it (that is, creating a new value of type s that is the same, except for a modified a). Then we can define a helper function
runInside :: (MonadState s m) => Lens' s a -> State a r -> m r
runInside lens s = lens %%= (runState s)
Given a lens and a stateful computation on a, we can lift such a computation to a stateful computation parametrized by s. The library allows us to generate lenses using Template Haskell, for example:
{-# LANGUAGE RankNTypes, TemplateHaskell #-}
import Control.Lens.TH
data ProgramState cs = ProgramState { _componentState :: cs }
$(makeLenses ''ProgramState)
will generate componentState :: Lens' ProgramState cs (actually the generated function will be slightly more more generic). Combining them together we get
runInside componentState :: MonadState (ProgramState a) m => State a r -> m r
Using Typeable we could go even further and create a map that automatically creates or keeps a state for whatever type it is asked for. I'd not recommend this approach in general, as it sort-of avoids Haskell's strong type system checks, but it might be useful in some cases.
{-# LANGUAGE ExistentialQuantification, ScopedTypeVariables, RankNTypes #-}
import Control.Lens
import Control.Lens.TH
import Control.Monad.State
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Typeable
data Something = forall a . Typeable a => Something a
type TypeMap = Map TypeRep Something
We defined a generic untyped container that can hold whatever is Typeable and a map that maps representation of types to their values.
We'll need some class to provide default/starting values:
class Default a where
getDefault :: a
-- just an example
instance Default Int where
getDefault = 0
Finally, we can create a lens that given an arbitrary Typeable type, it focuses on its value in the map by looking up its type representation:
typeLens :: forall t . (Typeable t, Default t) => Lens' TypeMap t
typeLens = lens get set
where
set map v = Map.insert (typeOf v) (Something v) map
get map = case Map.lookup (typeRep (Proxy :: Proxy t)) map of
Just (Something v) | Just r <- cast v -> r
_ -> getDefault
So you could have TypeMap somewhere in your state and let all stateful computations use it, regardless of what state they need.
However, there is a big warning: If two unrelated computations happen to use the same type for their state, they'll share the value with very likely disastrous results! So using explicit records for states of different parts of your computations is going to be much safer.

Data constructors without breaking the open/closed principle

I have a data constructor like this
class FooClass a where
foo :: a -> b
class BarClass a where
bar :: a -> b
data FooBar = Foo :: FooClass a => a -> IO ()
| Bar :: BarClass a => a -> IO ()
So that I can use pattern matching:
foobar :: FooBar -> a -> IO ()
foobar (Foo f) x = f (foo x)
foobar (Bar f) x = f (bar x)
However, this breaks the open/closed principle.
I'd like to be able to extend FooBar with additional methods based on other classes.
How would I implement this in Haskell?
As others have pointed out, this code is flawed in ways that obscure your question. It's also probably dangerous to try to think too hard about how OO principles translate to FP. They have a place, because much of OO is embedded in FP naturally, but it's much better to learn FP directly first and then observe the laws later as certain special cases.
In particular, we can talk about how greater refinement of types is a form of extension. For instance, comparing the types like
(Num a) => a -> IO ()
(Num a, Show a) => a -> IO ()
we can talk about how the second function takes in a set of types which is a natural subtype of the inputs to the first function. In particular, the set of possible types that can be input to the second function is a refinement of the inputs to the first. As users of these functions, there are fewer valid ways to use the second function. As implementers of these functions, there are more valid ways to implement the second function. In fact, we know the following
All values which are valid inputs to the second function are also valid inputs to the first
All functions which are correctly typed by the first signature are also correctly typed by the second.
This duality between giving and taking is explored in the study of Game semantics. The idea of "open for extension" plays out trivially in that we can always decide to ask for a more refined type, but it's almost completely uninteresting since that's just obvious in how refined types are used.
So what about ADTs (data declarations) directly? Are then Open/Closed? Mu—ADTs aren't objects, so the rule does not apply directly.
The trick to doing your example in Haskell is to use functions instead of classes:
-- FooBar is like a base class
-- with methods foo and bar.
-- I've interpreted your example liberally
-- for purposes of illustration.
-- In particular, FooBar has two methods -
-- foo and bar - with different signatures.
data FooBar = FooBar {
foo :: IO (),
bar :: Int -> Int
}
-- Use functions for classes, like in Javascript.
-- This doesn't mean Haskell is untyped, it just means classes are not types.
-- Classes are really functions that make objects.
fooClass :: Int -> FooBar
fooClass n = FooBar {
foo = putStrLn ("Foo " ++ show n)
bar = \n -> n+1
}
barClass :: FooBar
barClass = FooBar {
foo = putStrLn "Bar ",
bar = \n -> n * 2
}
-- Now we can define a function that uses FooBar and it doesn't matter
-- if the FooBar we pass in came from fooClass, barClass or something else,
-- bazClass, say.
foobar (FooBar foo bar) = do
-- invoke foo
foo
-- use bar
print (bar 7)
Here FooBar is 'open for extension' because we can create as many FooBar values as we like with different behaviours.
To 'extend' FooBar with another field, baz, without changing FooBar, fooClass or barClass, we need to declare a FooBarBaz type that includes a FooBar. We can still use our foobar function, we just have to first extract the FooBar from the FooBarBaz first.
So far, I've been keeping close to OOP. This is because Bertrand Meyer worded the open closed principle to require OOP or something very like it:
software entities (classes, modules, functions, etc.) should be open
for extension, but closed for modification
In particular, the word "extension" is traditionally interpreted as meaning "subclassing". If you're prepared to interpret the principle as merely "having extension points", then any function that takes another function as parameter is "open for extension". This is so common in functional programming that it's not considered a principle. The "parameterisation principle" just doesn't sound the same.

Is there a type 'Any' in haskell?

Say, I want to define a record Attribute like this:
data Attribute = Attribute {name :: String, value :: Any}
This is not valid haskell code of course. But is there a type 'Any' which basically say any type will do? Or is to use type variable the only way?
data Attribute a = Attribute {name :: String, value :: a}
Generally speaking, Any types aren't very useful. Consider: If you make a polymorphic list that can hold anything, what can you do with the types in the list? The answer, of course, is nothing - you have no guarantee that there is any operation common to these elements.
What one will typically do is either:
Use GADTs to make a list that can contain elements of a specific typeclass, as in:
data FooWrap where
FooWrap :: Foo a => a -> FooWrap
type FooList = [FooWrap]
With this approach, you don't know the concrete type of the elements, but you know they can be manipulated using elements of the Foo typeclass.
Create a type to switch between specific concrete types contained in the list:
data FooElem = ElemFoo Foo | ElemBar Bar
type FooList = [FooElem]
This can be combined with approach 1 to create a list that can hold elements that are of one of a fixed set of typeclasses.
In some cases, it can be helpful to build a list of manipulation functions:
type FooList = [Int -> IO ()]
This is useful for things like event notification systems. At the time of adding an element to the list, you bind it up in a function that performs whatever manipulation you'll later want to do.
Use Data.Dynamic (not recommended!) as a cheat. However, this provides no guarantee that a specific element can be manipulated at all, and so the above approaches should be preferred.
Adding to bdonlan's answer: Instead of GADTs, you can also use existential types:
{-# LANGUAGE ExistentialQuantification #-}
class Foo a where
foo :: a -> a
data AnyFoo = forall a. Foo a => AnyFoo a
instance Foo AnyFoo where
foo (AnyFoo a) = AnyFoo $ foo a
mapFoo :: [AnyFoo] -> [AnyFoo]
mapFoo = map foo
This is basically equivalent to bdonlan's GADT solution, but doesn't impose the choice of data structure on you - you can use a Map instead of a list, for example:
import qualified Data.Map as M
mFoo :: M.Map String AnyFoo
mFoo = M.fromList [("a", AnyFoo SomeFoo), ("b", AnyFoo SomeBar)]
The data AnyFoo = forall a. Foo a => AnyFoo a bit can also be written in GADT notation as:
data AnyFoo where
AnyFoo :: Foo a => a -> AnyFoo
There is the type Dynamic from Data.Dynamic which can hold anything (well, anything Typeable). But that is rarely the right way to do it. What is the problem that you are trying to solve?
This sounds like a pretty basic question, so I'm going to give an even more basic answer than anybody else. Here's what is almost always the right solution:
data Attribute a = Attribute { name :: String, value :: a }
Then, if you want an attribute that wraps an Int, that attribute would have type Attribute Int, or an attribute that wraps a Bool would have type Attribute Bool, etc. You can create these attributes with values of any type; for example, we can write
testAttr = Attribute { name = "this is only a test", value = Node 3 [] }
to create a value of type Attribute (Tree Int).
If your data needs to be eventually a specific type, You could use Convertible with GADTs. Because as consumer, you are only interested in a the datatype you need to consume.
{-# LANGUAGE GADTs #-}
import Data.Convertible
data Conv b where
Conv :: a -> (a -> b) -> Conv b
Chain :: Conv b -> (b -> c) -> Conv c
unconv :: (Conv b) -> b
unconv (Conv a f) = f a
unconv (Chain c f) = f $ unconv c
conv :: Convertible a b => a -> Conv b
conv a = (Conv a convert)
totype :: Convertible b c => Conv b -> Conv c
totype a = Chain a convert
It is not very difficult to derive functor, comonad and monad instances for this. I can post them if you are interested.
Daniel Wagner response is the right one: almost in 90% of cases using a polymorphic type is all that you need.
All the other responses are useful for the remaining 10% of cases, but if you have still no good knowledge of polymorphism as to ask this question, it will be extremely complicated to understand GADTs or Existential Types...
My advice is "keep it as simple as possible".

Operate on values within structurally similar types in Haskell

Excuse me for my extremely limited Haskell-fu.
I have a series of data types, defined in different modules, that are structured the same way:
-- in module Foo
data Foo = Foo [Param]
-- in module Bar
data Bar = Bar [Param]
-- * many more elsewhere
I'd like to have a set of functions that operate on the list of params, eg to add and remove elements from the list (returning a new Foo or Bar with a different list of params, as appropriate).
As far as I can tell, even if I create a typeclass and create instances for each type, I'd need to define all of these functions each time, ie:
-- in some imported module
class Parameterized a where
addParam :: a -> Param -> a
-- ... other functions
-- in module Foo
instance Parameterization Foo where
addParam (Foo params) param = Foo (param:params)
-- ... other functions
-- in module Bar
instance Parameterization Bar where
-- this looks familiar...
addParam (Bar params) param = Bar (param:params)
-- ... other functions
This feels tedious -- far past the degree where I start thinking I'm doing something wrong. If you can't pattern match regardless of constructor (?) to extract a value, how can boilerplate like this be reduced?
To rebut a possible line of argument: yes, I know I could simply have one set of functions (addParam, etc), that would explicitly list each constructor and pattern match put the params -- but as I'm building this fairly modularly (the Foo and Bar modules are pretty self-contained), and I'm prototyping a system where there will be dozens of these types, a verbose centralized listing of type constructors seems... wrong.
It's quite possible (probable?) that my approach is simply flawed and that this isn't anywhere near the right way to structure the type hierarchy anyhow -- but as I can't have a single data type somewhere and add a new constructor for the type in each of these modules (?) I'm stumped at how to get a nice "plugin" feel without having to redefine simple utility functions each time. Any and all kind suggestions gladly accepted.
You can have default implementations of functions in a typeclass, e.g.
class Parameterized a where
params :: a -> [Param]
fromParams :: [Param] -> a
addParam :: a -> Param -> a
addParam x par = fromParams $ par : params x
-- ... other functions
instance Parameterized Foo where
params (Foo pars) = pars
fromParams = Foo
However, your design does look suspicious.
You could use a newtype for Foo and Bar, and then deriving the implementation based on the underlying structure (in this case, lists) automatically with -XGenerializedNewtypeDeriving.
If they're really supposed to be structurally similar, yet you've coded it in a way that no code can be shared, then that is a suspicious pattern.
It's hard to tell from your example what would be the right way.
Why do you need both Foo and Bar if they are structurally similar? Can't you just go with Foo?
If, for some reason I can't see, you need both Foo and Bar you'll have to use a type class but you can clean up the code using Template Haskell.
Something like
$(superDuper "Foo")
could generate the code
data Foo = Foo [Param]
instance Parameterization Foo where
addParam (Foo params) param = Foo (param:params)
where
superDuper :: String -> Q [Dec]
superDuper n =
let name = mkName n
dataD = DataD [] name [] [NormalC name [] ] -- correct constructor here
instD = InstanceD [] ... -- add code here
return [dataD, instD]
That would at least get rid of the boiler plate coding.

Resources