I have a function that takes some time to process some input.
I want to make it so that if a user calls that function it would start doing what it does, but if the user calls it again and if it's still working on the thing, it'll return a message telling user to sit tight.
runService :: Arg1 -> Arg2 -> IO String
runService arg1 arg2 = do
isRunning <- {- Check if the function is running -}
isDone <- {- Check if the function is done working -}
if isRunning
then return "Work is in progress!"
else if isDone
then return "Work is done."
else do startService arg1 arg2
return "Work has been started."
I believe I'll need to modify startService function as well but I'm not sure how.
This is its current type signature.
startService :: Arg1 -> Arg2 -> IO ()
It would be even more useful if runService could provide a "progress bar" of sorts.
runService :: Arg1 -> Arg2 -> IO String
runService arg1 arg2 = do
isRunning <- {- Check if the function is running -}
isDone <- {- Check if the function is done working -}
if isRunning
then {- Return some progress indicator -}
else if isDone
then return "Work is done."
else do startService arg1 arg2
return "Work has been started."
{- Return some progress indicator -}
It is fairly simple for startService to print its status using putStrLn but I'm not certain how I'd supply these status strings to runService or how I'd thread this status upwards all the way to main.
For a procedural language, this would call for a global variable. Looking for something similar in Haskell led me to StateT, ReaderT, WriterT monad transformers but I am having a hard time understanding them and their usage in general and in this perticular context.
The type of design approach you propose looks heavily influenced by imperative programming background. Be careful with that, because although you can do imperative programming in Haskell, and mimic some common imperative patterns and behavior, going this way would be full of frustration, with no real benefit.
So you want to take a functional look at it :
you want to observe the state of a computation from an other computation, this means that you are going to need multiple threads for concurrency
you want to pass messages between threads, so you will need some primitives for message passing. Many options exists for that.
Basically, what you can do is share a concurrency primitive (think of a mutable box reference) between your computing thread and your observing thread. This is enough to implement common behavior, like synchronization (locking observing thread until computation finish and pass result) or waiting (is the computation done ? yes / no).
Observing progress is another matter involving cooperation from the computing function. If you can divide work in steps, you should probably use a continuation passing style so that you can keep your function pure. This function would do one step of a computation, then return a couple (estimated progress ration, next step).
An other function, this one in IO, would just keep calling the computation function and update the shared state with progress ratio, until work is done.
Inside the shared box, use an Algebraic Data Type :
data ComputationState result = Working Float -- progress ratio
| Done result -- done, get the result
Here you go.
Related
Recently, I started learning Haskell because I wanted to broaden my knowledge on functional programming and I must say I am really loving it so far. The resource I am currently using is the course 'Haskell Fundamentals Part 1' on Pluralsight. Unfortunately I have some difficulty understanding one particular quote of the lecturer about the following code and was hoping you guys could shed some light on the topic.
Accompanying Code
helloWorld :: IO ()
helloWorld = putStrLn "Hello World"
main :: IO ()
main = do
helloWorld
helloWorld
helloWorld
The Quote
If you have the same IO action multiple times in a do-block, it will be run multiple times. So this program prints out the string 'Hello World' three times. This example helps illustrate that putStrLn is not a function with side effects. We call the putStrLn function once to define the helloWorld variable. If putStrLn had a side effect of printing the string, it would only print once and the helloWorld variable repeated in the main do-block wouldn't have any effect.
In most other programming languages, a program like this would print 'Hello World' only once, since the printing would happen when the putStrLn function was called. This subtle distinction would often trip up beginners, so think about this a bit, and make sure you understand why this program prints 'Hello World' three times and why it would print it only once if the putStrLn function did the printing as a side effect.
What I don't understand
For me it seems almost natural that the string 'Hello World' is printed three times. I perceive the helloWorld variable (or function?) as a sort of callback which is invoked later. What I don't understand is, how if putStrLn had a side effect, it would result in the string being printed only once. Or why it would only be printed once in other programming languages.
Let's say in C# code, I would presume it would look like this:
C# (Fiddle)
using System;
public class Program
{
public static void HelloWorld()
{
Console.WriteLine("Hello World");
}
public static void Main()
{
HelloWorld();
HelloWorld();
HelloWorld();
}
}
I am sure I am overlooking something quite simple or misinterpret his terminology. Any help would be greatly appreciated.
EDIT:
Thank you all for your answers! Your answers helped me get a better understanding of these concepts. I don't think it fully clicked yet, but I will revisit the topic in the future, thank you!
It’d probably be easier to understand what the author means if we define helloWorld as a local variable:
main :: IO ()
main = do
let helloWorld = putStrLn "Hello World!"
helloWorld
helloWorld
helloWorld
which you could compare to this C#-like pseudocode:
void Main() {
var helloWorld = {
WriteLine("Hello World!")
}
helloWorld;
helloWorld;
helloWorld;
}
I.e. in C# WriteLine is a procedure that prints its argument and returns nothing. In Haskell, putStrLn is a function that takes a string and gives you an action that would print that string were it to be executed. It means that there is absolutely no difference between writing
do
let hello = putStrLn "Hello World"
hello
hello
and
do
putStrLn "Hello World"
putStrLn "Hello World"
That being said, in this example the difference isn’t particularly profound, so it’s fine if you don’t quite get what the author is trying to get at in this section and just move on for now.
it works a bit better if you compare it to python
hello_world = print('hello world')
hello_world
hello_world
hello_world
The point here being that IO actions in Haskell are “real” values that don’t need to be wrapped in further “callbacks” or anything of the sort to prevent them from executing - rather, the only way to do get them to execute is to put them in a particular place (i.e. somewhere inside main or a thread spawned off main).
This isn’t just a parlour trick either, this does end up having some interesting effects on how you write code (for example, it’s part of the reason why Haskell doesn’t really need any of the common control structures you’d be familiar with from imperative languages and can get away with doing everything in terms of functions instead), but again I wouldn’t worry too much about this (analogies like these don’t always immediately click)
It might be easier to see the difference as described if you use a function that actually does something, rather than helloWorld. Think of the following:
add :: Int -> Int -> IO Int
add x y = do
putStrLn ("I am adding " ++ show x ++ " and " ++ show y)
return (x + y)
plus23 :: IO Int
plus23 = add 2 3
main :: IO ()
main = do
_ <- plus23
_ <- plus23
_ <- plus23
return ()
This will print out "I am adding 2 and 3" 3 times.
In C#, you might write the following:
using System;
public class Program
{
public static int add(int x, int y)
{
Console.WriteLine("I am adding {0} and {1}", x, y);
return x + y;
}
public static void Main()
{
int x;
int plus23 = add(2, 3);
x = plus23;
x = plus23;
x = plus23;
return;
}
}
Which would print only once.
If the evaluation of putStrLn "Hello World" had side effects, then then message would only be printed once.
We can approximate that scenario with the following code:
import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (evaluate)
helloWorld :: ()
helloWorld = unsafePerformIO $ putStrLn "Hello World"
main :: IO ()
main = do
evaluate helloWorld
evaluate helloWorld
evaluate helloWorld
unsafePerformIO takes an IO action and "forgets" it's an IO action, unmooring it from the usual sequencing imposed by the composition of IO actions and letting the effect take place (or not) according to the vagaries of lazy evaluation.
evaluate takes a pure value and ensures that the value is evaluated whenever the resulting IO action is evaluated—which for us it will be, because it lies in the path of main. We are using it here to connect the evaluation of some values to the exection of the program.
This code only prints "Hello World" one time. We treat helloWorld as a pure value. But that means it will be shared between all evaluate helloWorld calls. And why not? It's a pure value after all, why recalculate it needlessly? The first evaluate action "pops" the "hidden" effect and the later actions just evaluate the resulting (), which doesn't cause any further effects.
There is one detail to notice: you call putStrLn function only once, while defining helloWorld. In main function you just use the return value of that putStrLn "Hello, World" three times.
The lecturer says that putStrLn call has no side effects and it's true. But look at the type of helloWorld - it is an IO action. putStrLn just creates it for you. Later, you chain 3 of them with the do block to create another IO action - main. Later, when you execute your program, that action will be run, that's where side effects lie.
The mechanism that lies in base of this - monads. This powerful concept allows you to use some side effects like printing in a language that doesn't support side effects directly. You just chain some actions, and that chain will be run on start of your program. You will need to understand that concept deeply if you want to use Haskell seriously.
I was learning how to use the State monad and I noticed some odd behavior in terms of the order of execution. Removing the distracting bits that involve using the actual state, say I have the following code:
import Control.Monad
import Control.Monad.State
import Debug.Trace
mainAction :: State Int ()
mainAction = do
traceM "Starting the main action"
forM [0..2] (\i -> do
traceM $ "i is " ++ show i
forM [0..2] (\j -> do
traceM $ "j is " ++ show j
someSubaction i j
)
)
Running runState mainAction 1 in ghci produces the following output:
j is 2
j is 1
j is 0
i is 2
j is 2
j is 1
j is 0
i is 1
j is 2
j is 1
j is 0
i is 0
Outside for loop
which seems like the reverse order of execution of what might be expected. I thought that maybe this is a quirk of forM and tried it with sequence which specifically states that it runs its computation sequentially from left to right like so:
mainAction :: State Int ()
mainAction = do
traceM "Outside for loop"
sequence $ map handleI [0..2]
return ()
where
handleI i = do
traceM $ "i is " ++ show i
sequence $ map (handleJ i) [0..2]
handleJ i j = do
traceM $ "j is " ++ show j
someSubaction i j
However, the sequence version produces the same output. What is the actual logic in terms of the order of execution that is happening here?
Haskell is lazy, which means things are not executed immediately. Things are executed whenever their result is needed – but no sooner. Sometimes code isn't executed at all if its result isn't needed.
If you stick a bunch of trace calls in a pure function, you will see this laziness happening. The first thing that is needed will be executed first, so that's the trace call you see first.
When something says "the computation is run from left to right" what it means is that the result will be the same as if the computation was run from left to right. What actually happens under the hood might be very different.
This is in fact why it's a bad idea to do I/O inside pure functions. As you have discovered, you get "weird" results because the execution order can be pretty much anything that produces the correct result.
Why is this a good idea? When the language doesn't enforce a specific execution order (such as the traditional "top to bottom" order seen in imperative languages) the compiler is free to do a tonne of optimisations, such as for example not executing some code at all because its result isn't needed.
I would recommend you to not think too much about execution order in Haskell. There should be no reason to. Leave that up to the compiler. Think instead about which values you want. Does the function give the correct value? Then it works, regardless of which order it executes things in.
I thought that maybe this is a quirk of forM and tried it with sequence which specifically states that it runs its computation sequentially from left to right like so: [...]
You need to learn to make the following, tricky distinction:
The order of evaluation
The order of effects (a.k.a. "actions")
What forM, sequence and similar functions promise is that the effects will be ordered from left to right. So for example, the following is guaranteed to print characters in the same order that they occur in the string:
putStrLn :: String -> IO ()
putStrLn str = forM_ str putChar >> putChar '\n'
But that doesn't mean that expressions are evaluated in this left-to-right order. The program has to evaluate enough of the expressions to figure out what the next action is, but that often does not require evaluating everything in every expression involved in earlier actions.
Your example uses the State monad, which bottoms out to pure code, so that accentuates the order issues. The only thing that a traversal functions such as forM promises in this case is that gets inside the actions mapped to the list elements will see the effect of puts for elements to their left in the list.
I'm trying to implement simple imperative language in haskell.
Generally speaking my program is a list of statements (like arithmetic expression, if/then, block statement). My evaluator has simple state: stack of lexical scopes. Lexical scope is just map of variable name to value. I push lexical scope every time as control flow enters function or block and pop as control flow leaves function or block.
But I've encountered a problem while trying to implement evaluation of return statement.
What I'm trying to do is to make a special case for return statement in main evaluating function(sources here):
evalStatements :: [Statement] -> Eval MaybeValue
-- nothing to evaluate
evalStatements [] = return Nothing
-- current statement is 'return expr',
-- evaluate expr and skip the rest of statements
evalStatements (ret#(ReturnStatement _expr):_stmts) =
leaveLexEnv -- leave current lexical scope
evalStatement ret >>= return
-- this is last statement in function, eval it and leave lexical scope
evalStatements [stmt] = do
res <- evalStatement stmt
leaveLexEnv -- leave current lexical scope
return res
evalStatements (st:stmts) =
evalStatement st >> evalStatements stmts >>= return
evalStatement :: Statement -> MaybeValue
evalStatement (ExprStatemet expr) = ...
evalStatement (IfThenStatement expr stmt) = ...
But special case in evalStatements function looks ugly for me. And this approach doesn't work with BlockStatement, because return statement can be inside this block statement.
Another problem is restoring stack of lexical scopes, when return statement is located inside multiple nested block statements.
I think I can solve this problem with storing some additional state in my evaluator, but this approach looks not very good. Something tells me that continuations can help me here. But I don't understand continuations very well yet.
What is best way to solve this problem? I need just an idea, general concept.
Thanks.
Continuations can work here, but they're way overkill. In fact, continuations are almost always overkill for solving any specific problem.
The simplest solution is to put the necessary logic into your Eval type. If you make Eval contain a constructor for "this computation returned early with this value", and then make your definitions of (>>) and (>>=) respect that, everything will work out automatically.
I'm using dynamicLogWithPP from XMonad.Hooks.DynamicLog together with dzen2 as a status bar under xmonad. One of the things I'd like to have displayed in the bar is the time remaining in the currently playing track in audacious (if any). Getting this information is easy:
audStatus :: Player -> X (Maybe String)
audStatus p = do
info <- liftIO $ tryS $ withPlayer p $ do
ispaused <- paused
md <- getMetadataString
timeleftmillis <- (-) <$> (getCurrentTrack >>= songFrames) <*> time
let artist = md ! "artist"
title = md ! "title"
timeleft = timeleftmillis `quot` 1000
(minutes, seconds) = timeleft `quotRem` 60
disp = artist ++ " - " ++ title ++ " (-"++(show minutes)++":"++(show seconds)++")" -- will be wrong if seconds < 10
audcolor False = dzenColor base0 base03
audcolor True = dzenColor base1 base02
return $ wrap "^ca(1, pms p)" "^ca()" (audcolor ispaused disp)
return $ either (const Nothing) Just info
So I can stick that in ppExtras and it works fine—except it only gets run when the logHook gets run, and that happens only when a suitable event comes down the pike. So the display is potentially static for a long time, until I (e.g.) switch workspaces.
It seems like some people just run two dzen bars, with one getting output piped in from a shell script. Is that the only way to have regular updates? Or can this be done from within xmonad (without getting too crazy/hacky)?
ETA: I tried this, which seems as if it should work better than it does:
create a TChan for updates from XMonad, and another for updates from a function polling Audacious;
set the ppOutput field in the PP structure from DynamicLog to write to the first TChan;
fork the audacious-polling function and have it write to the second TChan;
fork a function to read from both TChans (checking that they aren't empty, first), and combining the output.
Updates from XMonad are read from the channel and processed in a timely fashion, but updates from Audacious are hardly registered at all—every five or so seconds at best. It seems as if some approach along these lines ought to work, though.
I know this is an old question, but I came here looking for an answer to this a few days ago, and I thought I'd share the way I solved it. You actually can do it entirely from xmonad. It's a tiny bit hacky, but I think it's much nicer than any of the alternatives I've come across.
Basically, I used the XMonad.Util.Timer library, which will send an X event after a specified time period (in this case, one second). Then I just wrote an event hook for it, which starts the timer again, and then manually runs the log hook.
I also had to use the XMonad.Util.ExtensibleState library, because Timer uses an id variable to make sure it's responding to the right event, so I have to store that variable between events.
Here's my code:
{-# LANGUAGE DeriveDataTypeable #-}
import qualified XMonad.Util.ExtensibleState as XS
import XMonad.Util.Timer
...
-- wrapper for the Timer id, so it can be stored as custom mutable state
data TidState = TID TimerId deriving Typeable
instance ExtensionClass TidState where
initialValue = TID 0
...
-- put this in your startupHook
-- start the initial timer, store its id
clockStartupHook = startTimer 1 >>= XS.put . TID
-- put this in your handleEventHook
clockEventHook e = do -- e is the event we've hooked
(TID t) <- XS.get -- get the recent Timer id
handleTimer t e $ do -- run the following if e matches the id
startTimer 1 >>= XS.put . TID -- restart the timer, store the new id
ask >>= logHook.config -- get the loghook and run it
return Nothing -- return required type
return $ All True -- return required type
Pretty straightforward. I hope this is helpful to someone.
It cannot be done from within xmonad; xmonad's current threading model is a bit lacking (and so is dzen's). However, you can start a separate process that periodically polls your music player and then use one of the dzen multiplexers (e.g. dmplex) to combine the output from the two processes.
You may also want to look into xmobar and taffybar, which both have better threading stories than dzen does.
With regards to why your proposed TChan solution doesn't work properly, you might want to read the sections "Conventions", "Foreign Imports", and "The Non-Threaded Runtime" at my crash course on the FFI and gtk, keeping in mind that xmonad currently uses GHC's non-threaded runtime. The short answer is that xmonad's main loop makes an FFI call to Xlib that waits for an X event; this call blocks all other Haskell threads from running until it returns.
I'm having a hard time finding out how to make something change every time the user interacts with my program. It's hard to explain so here's an example (Haskell + wxhaskell):
simulate :: Int -> Frame () -> IO ()
simulate qNr window = do
fdata <- readFile "qarchive"
case (split (listTake (split fdata '\n') qNr 0) '#') of
(qst:a:b:c:coralt:answer:x) -> do
-- GUI Controls Initialization (buttons,text,etc...)
nextButton <- button window [text := "Next Question ->", on command := set infoField [text := "Next Question"], position := pt 185 155]
return ()
main :: IO ()
main = start gui
gui :: IO ()
gui = do
window <- frame [text := "Question program", clientSize := sz 640 480]
headerText <- staticText window [text := "Title Text", fontSize := 20, position := pt 5 5]
simulate 0 window
return ()
I want some widgets to change when the "Next Question" button is pressed. I want to change these widgets to some values I read from a file. How can I keep track of what the current question number is? I cannot actually increment questionNumber as a variable, since Haskell doesn't permit such things. I guess there's another way to do it.
Example:
Initialize GUI
Read data from file
If button is pressed, increment question number by 1 and change widgets.
How do you tackle this kind of problem in a functional manner?
The arguments to functions are your variables. As the user enters new values, pass those values to functions.
For example, a simple program that updates a value based on user input:
main = loop 0
loop n = do
print n
v <- read `fmap` getLine
loop (n + v)
Note the recursive calls to 'loop' have a different value passed each time, based on what the user provided.
This is a fundamental way of thinking in functional programming -- what would be a local, mutable variable in a loop in an imperative program becomes a parameter to a recursive function in a functional program.
Unfortunately, since wxHaskell is an event-based framework, Don's and ZachS answers don't apply.
What you have to do here is to allocate a mutable variable, just like you would in an imperative language. WxHaskell offers the function variable for that. Here an (incomplete) example:
gui = do
...
counter <- variable [value := 1 :: Int] -- allocate mutable variable
button <- button window [ text := "Count!"
, on command := next counter button]
where
next counter button = do
n <- get counter value -- get its value
set button [text := show n]
set counter [value := n+1] -- set its value
Note that wxHaskell comes with lots of example source code. In particular, wx/ImageViewer.hs features a mutable variable.
However, except for special situations like this, it is beneficial to avoid mutable variables like the plague. (In fact, they make a mess in wxHaskell, too, it's just that they are difficult to avoid here.) Alternatives include rethinking your code, accumulating parameters, using types of the form s -> (a,s) and the state monad.
One way to do this in a functional language is to thread your state through your functions. Some of the functionality will probably be handled by monads, such as getting the keyboard state, so you won't have to handle that yourself. An example (more or less pseudocode):
someFunction :: SomeDataTypeThatRepresentsState -> a ... -> (SDTTRS, a...) (change to fit reality of course)
someFunction x y .... | x == WeHaveKeyboardInput = someFunction dowhatever.....
| someFunction dowhateverelse
That should give you an idea of how to get started.
EDIT:
I should have mentioned Monads more in depth. Monads are basically a way to hide all of that state passing. It's oversimplified, I know, but it gets you started. To read more about monads and handling state, follow this link: http://www.engr.mun.ca/~theo/Misc/haskell_and_monads.htm
You might also want to check out the simple-observer package on Hackage. (Disclosure: I'm the package maintainer.)
It's a Haskell implementation of the Observer design pattern (just the ticket for solving "make something change every time ..." problems in an event-based framework), using MVars for mutable state. There's a blog post discussing it further here
I created this package when I was faced with exactly the same problem as you.