How to create monadic behaviour in reactive-banana - monads

Suppose I catch key presses and manipulate a code buffer accordingly:
let
bCode = accumB emptyCode eModifications
eCodeChanges <- changes bCode
I would like to create another behaviour bEval
bEval = accumB freshEnv (magic eCodeChanges)
which maps any state of code to its evaluation (triggered only when something really changes).
However, evaluation happens in a monad Interpreter (think hint from hackage). Can I actually define such a behaviour bEval? I guess I could just drag Interpreter String as the state in my behaviour, accumulating with currentAccumState >>= eval nextEvent, but where would I runInterpreter to actually force the evaluation?
Edit: Important thing is that the actions are not merely IO () but are supposed to modify some state. Consider for example clearing a buffer/reseting counter/moving around a zipper.
My idea was along the lines:
f :: a -> Maybe (b -> IO b)
mapJustIO :: (a -> Maybe (b -> IO b)) -> Event t a -> Event t (b -> IO b)
mapJustIO f e = filterJust $ f <$> e
accumIO :: a -> Event t (a -> IO a) -> Behaviour t (IO a)
accumIO z e = fold (>>=) (return z) e
I don't see why there could not be something like this. However, I don't see how to get rid of that IO in the behaviour either :).
Why aren't IO occurrences in reactive-banana actually only MonadIO?

The short answer is that combinators like accumB and so on can only work with pure functions. They can't work with functions from the IO monad (or another IO-like monad like Interpreter), because there is no way to define the order of actions in any meaningful way.
To work with IO actions, the combinators from Reactive.Banana.Frameworks are appropriate. For instance, you probably want a function like
mapIO' :: (a -> IO b) -> Event a -> MomentIO (Event b)
See a previous answer for more on this.
In the case of the Interpreter monad from hint, I recommend running it in the main thread, forking a separate thread for your FRP logic, and using TVars or TChan for communication between the two. (I like to calls this the forklift pattern). This way, you can access the Interpreter monad from IO.

Related

Using the >>= and =<< operators to combine IO in Haskell

I am trying to run an "infinite" simulation, printing the results of each step.
There's a function nextFrameR which takes an input Map and steps forward the simulation to return an output Map, and then there's a render_ function which takes an input Map and prints some things to stdout, returning the input Map (so that I can use iterate or something like it).
I'm really struggling to put all these pieces together as am relatively new to Haskell. I found this answer extremely interesting but am not sure how to put it directly into practice due to the combination of the two functions (I have tried playing with liftM2 and iterate).
The type signatures are as follows:
nextFrameR :: Map -> IO Map
render_ :: Map -> IO Map -- originally Map -> IO ()
I'm not really sure where to go from here, I can do something like:
(iterate (>>= nextFrameR) initialMap) :: [IO Map]
But that just gives me an (infinite?) list of frames (I think), which is great, it just doesn't let me print them as I don't know how to combine the rendering function in there.
iterate works fairly well for non-IO computation, but if you are in IO you can't easily exploit iterate.
To see why, your list
(iterate (>>= nextFrameR) initialMap) :: [IO Map]
is
[ initialMap
, initialMap >>= nextFrameR
, initialMap >>= nextFrameR >>= nextFrameR
...
so... how could we exploit that to have an infinite loop? We can't take the non-existent "last element". We also can't execute all the operations in that list in sequence, since that would run initialMap many times.
It's easier if we avoid using iterate and resort to basics like recursion:
loop :: Map -> IO ()
loop m = do
m' <- nextFrameR m
render_ m' -- it looks like you want this
-- feel free to add some delay here, or some stopping condition to exit the loop
loop m'
main :: IO ()
main = do
m <- initialMap
loop m
You can turn the above code into some code which uses >>= but there is no need to.
Finally, there's no need to make render_ return the same Map. You can make that return IO ().
If you are a beginner, I'd recommend to initially stay away from "smart" library functions like mapM_, traverse, for, sequence, liftM2, ap, ... and learn to do everything using only do-blocks and recursion. Then, once you get how this works, you can try to improve your code exploiting the library helpers.

Flat lists and free monads

I am trying to convince myself that the List monad (the one with flat lists, concatenation of lists and map element-wise) is not a free monad (to be precise, the free monad associated to some functor T). As far as I understand, I should be able to achieve that by
first finding a relation in the monad List between the usual operators fmap, join etc,
then showing that this relation does not hold in any free monad over a functor T, for all T.
What is a peculiar relation that holds in the List monad, that sets it apart from the free monads? How can I handle step2 if I don't know what T is? Is there some other strategy to show that flat lists are not free?
As a side note, to dispell any terminology clash, let me remark that the free monad associated to the pair functor is a tree monad (or a nested list monad), it is not the flat List monad.
Edit: for people acquainted with the haskell programming language, the question can be formulated as follows: how to show that there is no functor T such that List a = Free T a (for all T and up to monad isomorphism)?
(Adapted from my post in a different thread.)
Here is a full proof why the list monad is not free, including a bit of context.
Recall that we can construct, for any functor f, the free monad over f:
data Free f a = Pure a | Roll (f (Free f a))
Intuitively, Free f a is the type of f-shaped trees with leaves of type a.
The join operation merely grafts trees together and doesn't perform any
further computations. Values of the form (Roll _) shall be called
"nontrivial" in this posting. The task is to show that for no functor f, the monad Free f is isomorphic to the list monad.
The intuitive reason why this is true is because the
join operation of the list monad (concatenation) doesn't merely graft
expressions together, but flattens them.
More specifically, in the free monad over any functor, the result of binding a nontrivial
action with any function is always nontrivial, i.e.
(Roll _ >>= _) = Roll _
This can be checked directly from the definition of (>>=) for the free
monad.
If the list monad would be isomorphic-as-a-monad to the free monad over some
functor, the isomorphism would map only singleton lists [x] to values of
the form (Pure _) and all other lists to nontrivial values. This is
because monad isomorphisms have to commute with "return" and return x
is [x] in the list monad and Pure x in the free monad.
These two facts contradict each other, as can be seen with the following
example:
do
b <- [False,True] -- not of the form (return _)
if b
then return 47
else []
-- The result is the singleton list [47], so of the form (return _).
After applying a hypothetical isomorphism to the free monad over some
functor, we'd have that the binding of a nontrivial value (the image
of [False,True] under the isomorphism) with some function results in a
trivial value (the image of [47], i.e. return 47).
If you're okay with the free monad being applied to a type in particular which seems to be the case given the way you consider the Nat example given in the comments, then List can indeed be described using Free:
type List a = Free ((,) a) ()
The underlying idea here is that a List a is a Nat where each Suc node has been labelled with an a (hence the use of the (a,) functor rather than the Identity one).
Here is a small module witnessing the isomorphism together with an example:
module FreeList where
import Data.Function
import Control.Monad.Free
type List a = Free ((,) a) ()
toList :: [a] -> List a
toList = foldr (curry Free) (Pure ())
fromList :: List a -> [a]
fromList = iter (uncurry (:)) . fmap (const [])
append :: List a -> List a -> List a
append xs ys = xs >>= const ys
example :: [Integer]
example = fromList $ (append `on` toList) [1..5] [6..10]

Haskell working with Maybe lists

I'm pretty new to haskell and don't get how to work with Maybe [a]. Normally I'm coding OOP (VB.NET) and in my free time I want to learn haskell (don't ask why ;) ).
So, what do I want to do? I want to read two files with numerical IDs and find out only the IDs that match in both files. Reading the files is not a big thing, it works wonderfully easy. Now, I get two lists of Maybe[Ids] (for a simple example, just think the IDs are Int). So the function I need looks like this
playWithMaybe :: (Maybe [a]) -> (Maybe [Int]) -> [Int]
Now I want to access list members as I used to like this
playWithMaybe (x:xs) (y:ys) = undefined
But unfortunately it's not allowed, GHC says for both lists
Couldn't match expected type ‘Maybe [Int]’ with actual type ‘[t0]’
So I played around a little bit but didn't find a way to access list members. Can someone help me out? A little bit of explanation would be a great thing!
To approach your problem from a different direction, I would argue you don't want a function that processes two Maybe [a]. Bear with me:
Fundamentally, the operation you want to do operates on two lists to give you a new list, eg,
yourFunction :: [a] -> [a] -> [a]
yourFunction a b = ...
That's fine, and you can and should write yourFunction as such. The fact that the data you have is Maybe [a] captures some additional, auxiliary information: the operation that created your input lists may have failed. The next step is to chain together yourFunction with the auxiliary information. This is exactly the purpose of do notation, to mix pure operations (like yourFunction) with contexts (the fact that the creation of one of your input lists may have failed):
playWithMaybe :: Maybe [a] -> Maybe [a] -> Maybe [a]
playWithMaybe maybeA maybeB =
do a <- maybeA -- if A is something, get it; otherwise, pass through Nothing
b <- maybeB -- if B is something, get it; otherwise, pass through Nothing
Just (yourFunction a b) -- both inputs succeeded! do the operation, and return the result
But then it turns out there are other kinds of contexts you might want to work with (a simple one, instead of Maybe that just captures "something bad happened", we can use Either to capture "something bad happened, and here is a description of what happened). Looking back at playWithMaybe, the "Maybe-ness" only shows up in one place, the Just in the last line. It turns out Haskell offers a generic function pure to wrap a pure value, like what we get from yourFunction, in a minimal context:
playWithMaybe' :: Maybe [a] -> Maybe [a] -> Maybe [a]
playWithMaybe' maybeA maybeB =
do a <- maybeA
b <- maybeB
pure (yourFunction a b)
But then Haskell also has a generic type to abstract the idea of a context, the Monad. This lets us make our function even more generic:
playWithMonad :: Monad m => m [a] -> m [a] -> m [a]
playWithMonad mA mB =
do a <- mA
b <- mB
pure (yourFunction a b)
Now we have something very generic, and it turns out it is so generic, it's already in the standard library! (This is getting quite subtle, so don't worry if it doesn't all make sense yet.)
import Control.Applicative
play :: Monad m => m [a] -> m [a] -> m [a]
play mA mB = liftA2 yourFunction mA mB
or even
import Control.Applicative
play' :: Monad m => m [a] -> m [a] -> m [a]
play' = liftA2 yourFunction
Why did I switch from Monad to Applicative suddenly? Applicative is similar to Monad, but even more generic, so given the choice, it is generally better to use Applicative if you can (similar to my choice to use pure instead of return earlier). For a more complete explanation, I strongly recommend Learn You a Haskell (http://learnyouahaskell.com/chapters), in particular chapters 11 and 12. Note- definitely read chapter 11 first! Monads only makes sense after you have a grasp on Functor and Applicative.
In general:
yourFunction Nothing Nothing = ...
yourFunction (Just xs) Nothing =
case xs of
[] -> ...
x':xs' -> ...
-- or separately:
yourFunction (Just []) Nothing = ...
yourFunction (Just (x:xs)) Nothing = ...
et cetera. Which cases need to be treated separately depends on the specific function. More likely you would combine functions working on Maybe with functions working on [].
If you want to "Just return an list with no elements" for Nothing, then you can write
maybeToList1 :: Maybe [a] -> [a]
maybeToList1 Nothing = []
maybeToList1 (Just xs) = xs
A better way to write the same function is maybeToList1 = maybe [] id (docs for maybe) or maybeToList1 = fromMaybe [], but since you are just starting you may want to come back to this one later.
Like others have said, [Int] and Maybe [Int] are not the same thing. Maybe [Int] includes the extra information that the list may or may not be there. You said that you read the Ids from files. Perhaps, the Maybe signifies whether the file existed or not, while the empty list signifies that the file did exist but contained no Ids.
If you want to work with the list, you first need to define what to do if there is no list. You can use this function to extract the list:
fromMaybe :: a -> Maybe a -> a
Maybe you want to treat having no list the same as having an empty list:
fromMaybe [] :: Maybe [a] -> [a]
Maybe you want to crash the entire program:
fromMaybe (error "Missing list") :: Maybe a -> a
There is also the more general maybe function, which you can use if the default value is not of the same type as what's contained in the Maybe:
maybe :: b -> (a -> b) -> Maybe a -> b
Both these functions are defined in the module Data.Maybe.
You can also just work with the lists as if they existed and worry about their existence later by using Applicative. You said you wanted to find the Ids common to both lists. You can do it like this:
maybeCommonIds :: Maybe [Int] -> Maybe [Int] -> Maybe [Int]
maybeCommonIds xs ys = intersect <$> xs <*> ys
intersect is defined in Data.List. Using maybeCommonIds will result in Maybe [Int]. The list contained inside will hold the common ids, but if either of the two lists did not exist, there is not list of common ids. In your case, this might be the same as having no common ids. In that case, you might want to pass the result to fromMaybe [], to get back the list.

Haskell I/O: Filtering empty lists in CSV data-set

Once again I'm stuck with haskell. This time I'm supposed to filter a CSV-dataset, using IO which I'm struggling to understand. Any additional related information is appreciated.
The structure is predetermined, and to me it seems messy. Is this really how one should do it? (I still have to do it this way, so this is a little "on the side"-question).
getRawData' :: String -> IO [[String]]
getRawData' fn = do
s <- readFile fn
return $ parseCSVsimple s
getRawData :: String -> IO [[String]]
getRawData fn = do
d <- getRawData' fn
return (dropEmpty d)
dropEmpty [[String]] -> [[String]]
DropEmpty - This is where I need help For a "normal" list I would just filter it straightforward, but this IO and different functions calling each other has me confused.
Sorry for stupid questions, I've programmed for 8 months and had to use 6-7 languages since then. Any general information related to the question is very much appreciated as well.
EDIT; FOLLOW-UP:
Thanks to good answers I have improved my understanding and implemented the following code:
dropEmpty :: [[String]] -> [[String]]
dropEmpty = filter(not . null)
However, I still see empty lists in the list. Is this because I am checking if the whole list of lists is empty? How do I sepcify that I want to check the "internal" lists?
The do keyword is just a sugar syntax for monads
Monad are defined like this:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
Your getRawData function is equivalent to
getRawData fn = getRawData' fn >>= \d -> return (dropEmpty d)
As you can see in the monad definition, the second argument of >>= is the inner type of the monad, in your case, it's [[String]]
So there is nothing wrong with your code, you can use your dropEmpty without worrying about IO
getRawData :: String -> IO [[String]]
getRawData fn = do
d <- getRawData' fn
return (dropEmpty d)
getRawData and return are the monadic actions in this do block. All other expressions do not have the IO type.
In particular, the expression to the left of <-, namely d, has just the plain type [[String]]. All parameters, namely fn :: String and (dropEmpty d) :: [[String]], are also not in IO.
So you can get non-monadic values (e.g. d) out of the monadic actions (e.g. getRawData') easily. However, you can only do so temporarily: You cannot make d escape the do block, only IO d. This is a "core feature" of monads in general.
This is only a very superficial explanation to give you a quick start on monadic code. I recommend you read up on monads. Learn how monads are desugared. Take the state monad for example, and understand what problem it solves by trying to re-implement it.

Why do we have map, fmap and liftM?

map :: (a -> b) -> [a] -> [b]
fmap :: Functor f => (a -> b) -> f a -> f b
liftM :: Monad m => (a -> b) -> m a -> m b
Why do we have three different functions that do essentially the same thing?
map exists to simplify operations on lists and for historical reasons (see What's the point of map in Haskell, when there is fmap?).
You might ask why we need a separate map function. Why not just do away with the current
list-only map function, and rename fmap to map instead? Well, that’s a good question. The
usual argument is that someone just learning Haskell, when using map incorrectly, would much
rather see an error about lists than about Functors.
-- Typeclassopedia, page 20
fmap and liftM exist because monads were not automatically functors in Haskell:
The fact that we have both fmap and liftM is an
unfortunate consequence of the fact that the Monad type class does not require
a Functor instance, even though mathematically speaking, every monad is a
functor. However, fmap and liftM are essentially interchangeable, since it is
a bug (in a social rather than technical sense) for any type to be an instance
of Monad without also being an instance of Functor.
-- Typeclassopedia, page 33
Edit: agustuss's history of map and fmap:
That's not actually how it happens. What happened was that the type of map was generalized to cover Functor in Haskell 1.3. I.e., in Haskell 1.3 fmap was called map. This change was then reverted in Haskell 1.4 and fmap was introduced. The reason for this change was pedagogical; when teaching Haskell to beginners the very general type of map made error messages more difficult to understand. In my opinion this wasn't the right way to solve the problem.
-- What's the point of map in Haskell, when there is fmap?