Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Maybe Return? (Ramnath R Iyer) 2. Re: Maybe Return? (Francesco Ariis) 3. Re: Maybe Return? (Ramnath R Iyer) 4. Re: Maybe Return? (Francesco Ariis) 5. Re: reading lines with history from bash terminal in OS X (Dennis Raddle) ---------------------------------------------------------------------- Message: 1 Date: Sun, 31 Jul 2016 18:44:14 +0000 From: Ramnath R Iyer <casual.d...@gmail.com> To: beginners@haskell.org Subject: [Haskell-beginners] Maybe Return? Message-ID: <CACL-Fmw6106xaci9T9eOL4U5ut2z=qssdrmfp+mr1fv1mew...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hi all, I'm trying to write a fairly simple program to understand Haskell in practice. I am implementing a simple REPL where I can write some text, and that text can be parsed into a command with arguments. Then, I would like to be able to turn this into a 'plugin' system of sorts, with a module/logic per command. I understand the Text.Parsec library may already provide these things out of the box, but for now, I would prefer to reinvent the wheel. The program below is what I have working right now (very trivial). I want to modify this program, so that the `evaluate input` returns not a String, but a type X that includes information on whether to "continue" and show a prompt after rendering the result, or exit altogether. So the specific questions I have here are: 1. What would be a sensible type signature for X? 2. Assuming X to exist, what is the right way to modify main to use it? My current intuition is to modify the outputStrLn ... loop statements to include an if-then-else, but I'm not sure what the right modification is (all my attempts seemed like imperative programming and failed compilation unsurprisingly). import Evaluator import System.Console.Haskeline main :: IO () main = runInputT defaultSettings loop where loop :: InputT IO () loop = do line <- getInputLine ">> " case line of Nothing -> return () Just "quit" -> return () Just input -> do outputStrLn $ "Executing: " ++ (evaluate input) loop module Evaluator where evaluate :: String -> String evaluate value = value -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160731/63beb504/attachment-0001.html> ------------------------------ Message: 2 Date: Sun, 31 Jul 2016 20:55:56 +0200 From: Francesco Ariis <fa...@ariis.it> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Maybe Return? Message-ID: <20160731185556.ga4...@casa.casa> Content-Type: text/plain; charset=us-ascii On Sun, Jul 31, 2016 at 06:44:14PM +0000, Ramnath R Iyer wrote: > The program below is what I have working right now (very trivial). I want > to modify this program, so that the `evaluate input` returns not a String, > but a type X that includes information on whether to "continue" and show a > prompt after rendering the result, or exit altogether. So the specific > questions I have here are: > > 1. What would be a sensible type signature for X? Hello Ramnath, as now evaluate *has to* return a String because you pass its output as an argument to outputStrLn (which has a ~ `String -> InputT IO ()` signature itself). A quick hack is for `evaluate` to return evaluate :: String -> (String, Bool) where the Bool stands for 'should I exit or not' (using a datatype and/or a type synonym would be better and more clear). You can then write let (s, b) = evaluate input outputStrLn $ "Something " ++ s if b then loop else exit Your code has a very distinct imperative flavour (there are ways to get rid of that case/if cascade), but my opinion is: first make it work, then make it pretty. Does that help? -F ------------------------------ Message: 3 Date: Sun, 31 Jul 2016 21:17:09 +0000 From: Ramnath R Iyer <r...@silentyak.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Maybe Return? Message-ID: <CACL-Fmy1Ra1UorSVtgM9dk7JdQt8thr-V4+_SpFm1B5NWX_=4...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hi Francesco, Thank you for your response, it definitely helped. Below is an updated version of working code. Where I was getting tripped up earlier was in the commented portion below. Also, if you scroll down further, I have a few further questions. Thank you for your time. module Main where import Evaluator import System.Console.Haskeline main :: IO () main = runInputT defaultSettings loop where loop :: InputT IO () loop = do line <- getInputLine ">> " case line of Nothing -> return () Just input -> do let (result, next) = evaluate input if (next == Return) then return () else (emit result >> loop) -- I had wanted the result to be emitted only on Continue, not Return. This works, but is it a good way? emit :: Maybe String -> InputT IO () emit Nothing = return () emit (Just value) = outputStrLn $ "Executing: " ++ value module Evaluator where data Next = Continue | Return deriving (Eq, Ord) evaluate :: String -> (Maybe String, Next) -- Now updated to make the first part of the tuple a Maybe String instead of String evaluate "quit" = (Nothing, Return) evaluate value = (Just value, Continue) ** QUESTIONS ** 1. If I wanted to write the logic encapsulated in `emit' directly within main, how would I do that? In my example, I was forced to extract it out as a separate method specifically to leverage pattern matching. 2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do you logically come to this conclusion? Is it because outputStrLn was taking a single String argument and had to return the same type returned by loop declared previously? 3. Are there better/simpler/more idiomatic ways of structuring my program? On Sun, Jul 31, 2016 at 12:01 PM Francesco Ariis <fa...@ariis.it> wrote: > On Sun, Jul 31, 2016 at 06:44:14PM +0000, Ramnath R Iyer wrote: > > The program below is what I have working right now (very trivial). I want > > to modify this program, so that the `evaluate input` returns not a > String, > > but a type X that includes information on whether to "continue" and show > a > > prompt after rendering the result, or exit altogether. So the specific > > questions I have here are: > > > > 1. What would be a sensible type signature for X? > > Hello Ramnath, > > as now evaluate *has to* return a String because you pass its output as > an argument to outputStrLn (which has a ~ `String -> InputT IO ()` > signature itself). > > A quick hack is for `evaluate` to return > > evaluate :: String -> (String, Bool) > > where the Bool stands for 'should I exit or not' (using a datatype > and/or a type synonym would be better and more clear). > You can then write > > let (s, b) = evaluate input > outputStrLn $ "Something " ++ s > if b then loop > else exit > > Your code has a very distinct imperative flavour (there are ways > to get rid of that case/if cascade), but my opinion > is: first make it work, then make it pretty. > > Does that help? > -F > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160731/5b1442e4/attachment-0001.html> ------------------------------ Message: 4 Date: Sun, 31 Jul 2016 23:51:32 +0200 From: Francesco Ariis <fa...@ariis.it> To: beginners@haskell.org Subject: Re: [Haskell-beginners] Maybe Return? Message-ID: <20160731215132.ga7...@casa.casa> Content-Type: text/plain; charset=utf-8 On Sun, Jul 31, 2016 at 09:17:09PM +0000, Ramnath R Iyer wrote: > Below is an updated version of working code. > [...] Well done! Now, to the questions: > 1. If I wanted to write the logic encapsulated in `emit' directly within > main, how would I do that? In my example, I was forced to extract it out as > a separate method specifically to leverage pattern matching. Pattern matching can be done via a `case` statement as well (and you provide an example of this just a few lines above the `emit` call). Personally, I much a prefer separate function as it is clearer (if you don't want to clutter top level use a `where` statement). > 2. You mentioned outputStrLn has a type `String -> InputT IO ()'. How do > you logically come to this conclusion? Is it because outputStrLn was taking > a single String argument and had to return the same type returned by loop > declared previously? Correct, if we ask ghci about `ouputStrLn` it will reply: λ> :t outputStrLn outputStrLn :: Control.Monad.IO.Class.MonadIO m => String -> InputT m () but in this case you have written the signature to `loop` (it's always a good habit), so it's clear our function can only have this concrete data type. > 3. Are there better/simpler/more idiomatic ways of structuring my program? Yes there are: your program checks/pattern matches at every step and for each of those you have a case/if; it could get pretty messy if you were to add a few more actions. There is a nice way to handle these kind of situations, it involves monadic code. But before using monads you need to digest them! So keep following your course (if you are not following any, I like these two, which are gratis [1] [2]) and come back to this .hs after you tamed the mighty monad to refactor it! [1] http://learnyouahaskell.com/ [2] https://www.seas.upenn.edu/~cis194/spring13/lectures.html ------------------------------ Message: 5 Date: Mon, 1 Aug 2016 01:06:05 -0700 From: Dennis Raddle <dennis.rad...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] reading lines with history from bash terminal in OS X Message-ID: <cakxlvoo7vxn5nj9ykwqfejbu46qprcldq4muchvyvwpw40p...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" I'm looking over haskeline. It looks like I have to modify some of my code that is in the IO monad right now. I use 'evaluate' in several places, and also 'evaluate $ force', to make sure that IO exceptions are encountered where I can catch them. Can I use 'evaluate' with InputT? I'm muddled headed about what to do. I guess I would lift 'evaluate' into the inner monad? I am not sure what those words mean. How would I catch IO exceptions? On Thu, Jul 28, 2016 at 5:35 PM, Dennis Raddle <dennis.rad...@gmail.com> wrote: > Thanks. I'll install haskeline > > On Thu, Jul 28, 2016 at 5:05 PM, David McBride <toa...@gmail.com> wrote: > >> You will have to use the haskeline library. FYI that is the library that >> makes ghci work. >> >> On Thu, Jul 28, 2016 at 6:09 PM, Dennis Raddle <dennis.rad...@gmail.com> >> wrote: >> >>> I wrote a program first in Windows, where it works as expected, and now >>> I'm using it in OS X and getting undesired behavior. >>> >>> It reads lines from the terminal using the getLine function. In Windows >>> (DOS, actually) the up and down arrows can be used to choose previously >>> entered lines. However, this does not work in bash in OS X. >>> >>> What do I need to get the history available via the arrow keys? >>> >>> D >>> >>> >>> _______________________________________________ >>> Beginners mailing list >>> Beginners@haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >>> >>> >> >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20160801/ad38cc73/attachment.html> ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 98, Issue 1 ****************************************