[Haskell-cafe] How to define a Monad instance

Johan Holmquist holmisen at gmail.com
Sun Jul 29 11:43:49 CEST 2012


As for understanding monads, you can try to define the State monad
[1]. Not sure if it's the best example but it's intuitive in that it
let's you thread a state "behind the scenes".

***

Not related to your question -- in your example if you want to
translate characters but do not plan to change the length of the
input, you don't need Maybe. Your 'table' can then be defined as:

table :: Char -> Char
table 'a' = 'b'
table 'A' = 'B'
table x  = x

Then your 'replaceAll' is simply 'map':

replaceAll = map

/Johan

[1] http://hackage.haskell.org/packages/archive/mtl/2.1.2/doc/html/Control-Monad-State-Lazy.html

2012/7/28 Steffen Schuldenzucker <sschuldenzucker at uni-bonn.de>:
> On 07/28/2012 03:35 PM, Thiago Negri wrote:
>> [...]
>
>> As Monads are used for sequencing, first thing I did was to define the
>> following data type:
>>
>> data TableDefinition a = Match a a (TableDefinition a) | Restart
>
>
> So TableDefinition a is like [(a, a)].
>
>> [...]
>
>>
>>
>> So, to create a replacement table:
>>
>> table' :: TableDefinition Char
>> table' =
>>          Match 'a' 'b'
>>          (Match 'A' 'B'
>>           Restart)
>>
>> It look like a Monad (for me), as I can sequence any number of
>> replacement values:
>>
>> table'' :: TableDefinition Char
>> table'' = Match 'a' 'c'
>>           (Match 'c' 'a'
>>           (Match 'b' 'e'
>>           (Match 'e' 'b'
>>            Restart)))
>
>
> Yes, but monads aren't just about sequencing. I like to see a monad as a
> generalized computation (e.g. nondeterministic, involving IO, involving
> state etc). Therefore, you should ask yourself if TableDefinition can be
> seen as some kind of abstract "computation". In particular, can you
> "execute" a computation and "extract" its result? as in
>
>   do
>     r <- Match 'a' 'c' Restart
>     if r == 'y' then Restart else Match 2 3 (Match 3 4 Restart)
>
> Doesn't immediately make sense to me. In particular think about the
> different possible result types of a TableDefinition computation.
>
> If all you want is sequencing, you might be looking for a Monoid instance
> instead, corresponding to the Monoid instance of [b], where b=(a,a) here.
>
>>  [...]
>
>>
>>
>> I'd like to define the same data structure as:
>>
>> newTable :: TableDefinition Char
>> newTable = do
>>          'a' :>  'b'
>>          'A' :>  'B'
>>
>> But I can't figure a way to define a Monad instance for that. :(
>
>
> The desugaring of the example looks like this:
>
>   ('a' :> 'b') >> ('A' :> 'B')
>
> Only (>>) is used, but not (>>=) (i.e. results are always discarded). If
> this is the only case that makes sense, you're probably looking for a Monoid
> instead (see above)
>
> -- Steffen
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list