I want to read values(strings) from console in a loop until a certain value is entered.
What is the code for that?
With Haskell there are a multitude ways of writing such a loop, and the one you choose will depend on context -- i.e. what larger program is this loop part of?
To get you started with some simple imperative-style loops, both the Haskell Wikibook and the Haskell Wiki have some good resources:
Haskell Simple Input and Output
IO for Imperative Programmers
Update
From your comment it appears you want to write a "command processor". Have a look at this SO question and answer:
Number guessing game error and keeping count of guesses
Alternatively, if your bool expression type has a Show instance how about using the REPL in ghci?
ghci> :load your_code
ghci> let e = ...initial bool expression...
ghci> e
...e is displayed...
ghci> let f = e || blah
ghci> f
...f is displayed...
ghci> it && whatever -- it refers to the last expression
...some output...
ghci> not it
...
it is a variable maintained by ghci which always refers to the last evaluated expression.
Related
I am trying to parse the following code using parsec
for x = Int in [1, 2, 3]
print x + 1
The only part of the example that might be hard to understand is x = Int which means the variable x is defined as an Int. Syntactically Int here is an expression. It might just as well be replaced with a function call that returns a type.
So far I have been able to parse all the simple literals and operators. My problem now is that in this language in is a keyword as well as an operator and types (Int) are objects like any other (that can be in lists). E.g. the following code is perfectly valid and prints false
print (Int in [1, 2, 3])
So right now my parser parses for x = correctly and then it parses Int in [1, 2, 3] as ONE expression. How can I make the for parser grab the in instead of leaving it to the expression parser? I have a feeling that parsec has something like that built in, but I have no idea how to find it.
Edit: I changed the example to make more sense...
Edit: I have this difficulty in various places, the language is very complex. Another example is the else operator which returns it's second argument if it's first argument is null:
print (if true then (null else "hello") else "world")
# >> hello
print (if true then null else "hello" else "world")
# >> world
Thank you very much #talex and #n.m. for pointing me where I had to look. This is how I solved this specific problem:
I parameterized the expression parser (had to enable {-# LANGUAGE FlexibleContexts #-}) with a list of "eject" words and equally every relevant parser below it, specifically the binOperator parser
expression :: [String] -> MyParser AST
binOperator :: [String] -> MyParser AST
If one of the "eject"-words is encountered in the position of a binary operator, the binOperator parser fails (and with the chainl1 based parser that reads binary operations), thus leaving the "eject" word (in this case in) to the for parser to consume. This should work just as well with the if parser.
And I simply don't pass the eject words to the paren parser so there are no eject words recognized between ( and ) (and similar parsers like list).
I'm taking a Haskell course at school, and I have to define a Logical Proposition datatype in Haskell. Everything so far Works fine (definition and functions), and i've declared it as an instance of Ord, Eq and show. The problem comes when I'm required to define a program which interacts with the user: I have to parse the input from the user into my datatype:
type Var = String
data FProp = V Var
| No FProp
| Y FProp FProp
| O FProp FProp
| Si FProp FProp
| Sii FProp FProp
where the formula: ¬q ^ p would be: (Y (No (V "q")) (V "p"))
I've been researching, and found that I can declare my datatype as an instance of Read.
Is this advisable? If it is, can I get some help in order to define the parsing method?
Not a complete answer, since this is a homework problem, but here are some hints.
The other answer suggested getLine followed by splitting at words. It sounds like you instead want something more like a conventional tokenizer, which would let you write things like:
(Y
(No (V q))
(V p))
Here’s one implementation that turns a string into tokens that are either a string of alphanumeric characters or a single, non-alphanumeric printable character. You would need to extend it to support quoted strings:
import Data.Char
type Token = String
tokenize :: String -> [Token]
{- Here, a token is either a string of alphanumeric characters, or else one
- non-spacing printable character, such as "(" or ")".
-}
tokenize [] = []
tokenize (x:xs) | isSpace x = tokenize xs
| not (isPrint x) = error $
"Invalid character " ++ show x ++ " in input."
| not (isAlphaNum x) = [x]:(tokenize xs)
| otherwise = let (token, rest) = span isAlphaNum (x:xs)
in token:(tokenize rest)
It turns the example into ["(","Y","(","No","(","V","q",")",")","(","V","p",")",")"]. Note that you have access to the entire repertoire of Unicode.
The main function that evaluates this interactively might look like:
main = interact ( unlines . map show . map evaluate . parse . tokenize )
Where parse turns a list of tokens into a list of ASTs and evaluate turns an AST into a printable expression.
As for implementing the parser, your language appears to have similar syntax to LISP, which is one of the simplest languages to parse; you don’t even need precedence rules. A recursive-descent parser could do it, and is probably the easiest to implement by hand. You can pattern-match on parse ("(":xs) =, but pattern-matching syntax can also implement lookahead very easily, for example parse ("(":x1:xs) = to look ahead one token.
If you’re calling the parser recursively, you would define a helper function that consumes only a single expression, and that has a type signature like :: [Token] -> (AST, [Token]). This lets you parse the inner expression, check that the next token is ")", and proceed with the parse. However, externally, you’ll want to consume all the tokens and return an AST or a list of them.
The stylish way to write a parser is with monadic parser combinators. (And maybe someone will post an example of one.) The industrial-strength solution would be a library like Parsec, but that’s probably overkill here. Still, parsing is (mostly!) a solved problem, and if you just want to get the assignment done on time, using a library off the shelf is a good idea.
the read part of a REPL interpreter typically looks like this
repl :: ForthState -> IO () -- parser definition
repl state
= do putStr "> " -- puts a > character to indicate it's waiting for input
input <- getLine -- this is what you're looking for, to read a line.
if input == "quit" -- allows user to quit the interpreter
then do putStrLn "Bye!"
return ()
else let (is, cs, d, output) = eval (words input) state -- your grammar definition is somewhere down the chain when eval is called on input
in do mapM_ putStrLn output
repl (is, cs, d, [])
main = do putStrLn "Welcome to your very own interpreter!"
repl initialForthState -- runs the parser, starting with read
your eval method will have various loops, stack manipulations, conditionals, etc to actually figure out what the user inputted. hope this helps you with at least the reading input part.
I'm starting out to learn Haskell. Even though I'm a dunce extraordinaire, I am intent on making this work. The error I received is listed as the title. This is the code that I wrote to try to implement the behavior of replicating a list (n) times and concatenating its new length as a new list. Now I have a basic understanding of how parsing works in Haskell, below my original code I will give example of some modified code to see if my understanding on parsing is adequate. My question for now is how I can properly indent or structure my block in order to not receive this error (is that specific enough :O) -- is there a piece of information I'm missing when it comes to creating instances and formatting? PLEASE DO NOT TELL ME OR OFFER SUGGESTIONS IF YOU NOTICE THAT MY CURRENT INSTANCE OR MAIN FUNCTION ARE SYNTACTICALLY WRONG. I want to figure it out and will deal with that GHC error when I get to it. (I hope that's the proper way to learn). BUT if I could ask for anyone's help in getting past this first obstacle in understanding proper formatting, I'd be grateful.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where
x = []
n = replicate >>= x : (n:xs)
stutter >>= main = concat [x:xs]
let stutter 6 "Iwannabehere" -- <-- parse error occurs here!!!
--Modified code with appropriate brackets, at least where I think they go.
module Main where
import Data.List
n :: Int
x :: [Char]
instance Data stutter n x where{
;x = []
;n = replicate >>= x : (n:xs)
;stutter >>= main = concat [x:xs]
;
};let stutter 6 "Iwannabehere" -- there should be no bracket of any kind at the end of this
I placed the 'let' expression on the outside of the block, I don't believe it goes inside and I also receive a parsing error if I do that. Not correct but I thought I'd ask anyway.
I'm not sure what the instance Data stutter n x is supposed to be, the instance XYZ where syntax is used solely for typeclasses, but you have a couple syntax errors here.
First of all, while GHC says that the error is on let stutter 6 "Iwannabehere", your first error occurs before that with stutter >>= main = concat [x:xs]. A single = sign is reserved for assignments, which are merely definitions. You can have assignments at the top level, inside a where block, or inside a let block (the where includes typeclass instance definitions). You can't have an assignment be part of an expression like x >>= y = z.
Your next syntax error is the let itself. let blocks can not appear at the top level, they only appear within another definition. You use let in GHCi but the reasons for that are outside the scope of this answer. Suffice to say that entering expression in GHCi is not equivalent to the top level of a source file.
Next, if you were to use a let block somewhere, it can only contain definitions. The syntax looks more like
let <name> [<args>] = <definition>
[<name> [<args>] = <definition>]
in <expression>
And this whole block makes an expression. For example, you could write
def f(x, y, z):
w = x + y + z
u = x - y - z
return w * u
in Python, and this would be equivalent to the Haskell function definition
f x y z = let w = x + y + z
u = x - y - z
in w * u
It only defines local variables. There is another form when you're using it inside do blocks where you can exclude the in <expression> part, such as
main = do
name <- getLine
let message = if length name > 5 then "short name" else "long name"
goodbye n = putStrLn ("Goodbye, " ++ n)
putStrLn message
goodbye name
Note that there is no need to use in here. You can if you want, it just means you have to start a new do block:
main = do
name <- getLine
let message = ...
goodbye n = ...
in do
putStrLn message
goodbye name
And this isn't as pretty.
Hopefully this points you more towards correct syntax, but it looks like you have some misunderstandings about how Haskell works. Have you looked at Learn You a Haskell? It's a pretty gentle and fun introduction to the language that can really help you learn the syntax and core ideas.
Your parse error is from the let keyword. Remove it and no error related to that will occur. let x = y is only relevant in GHCi and do-blocks, neither of which is relevant at this point. Essentially, just replace it with this line:
theWordIGet = stutter 6 "Iwannabehere"
Secondly, instance keyword in Haskell has absolutley nothing to do with what you want to do at this stage. This is not how Haskell functions are defined, which is what I'm guessing you want to do. This is what you're wanting to do to create a stutter function, assuming it simply repeats a string n times.
stutter :: Int -> String -> String
stutter n x = concat (replicate n x)
You'll also want to remove the type declarations for the (out-of-scope) values n and x: they're not objects, they're arguments for a function, which has its own signature determining the types of n and x within a function call.
Lastly, I imagine you will want to print the value of stutter 6 "Iwannabehere" when the program is executed. To do that, just add this:
main :: IO ()
main = print (stutter 6 "Iwannabehere")
In conclusion, I implore you to start from scratch and read 'Learn You a Haskell' online here, because you're going off in entirely the wrong direction - the program you've quoted is a jumble of expressions that could have a meaning, but are in the wrong place entirely. The book will show you the syntax of Haskell much better that I can write about in this one answer, and will explain fully how to make your program behave in the way you expect.
I'm writing a lexer for a small language in Alex with Haskell.
The language is specified to have pythonesque significant indentation, with an INDENT token or a DEDENT token emitted whenever the indentation level changes.
In a traditional imperative language like C, you'd keep a global in the lexer and update it with the indentation level at each line.
This doesn't work in Alex/Haskell because I can't store any global data anywhere with Haskell, and I can't put all my lexing rules inside any monad or anything.
So, how can I do this? Is it even possible? Or will i have to write my own lexer and avoid using alex?
Note that in other whitespace-sensitive languages -- like Haskell -- the layout handling is indeed done in the lexer. GHC in fact implements layout handling in Alex. Here's the source:
https://github.com/ghc/ghc/blob/master/compiler/GHC/Parser/Lexer.x
There are some serious errors in your question that lead you astray, as jrockway points out. "I can't store any global data anywhere with Haskell" is on the wrong track. Firstly, you can have global state, secondly, you should not be using global state here, when Alex fully supports state transitions in rules in a safe manner.
Look at the AlexState structure that Alex provides, letting you thread state through your lexer. Then, look at how the state is used in GHC's layout implementation to implement indent/unindent of the layout rules. (Search for "-- Layout processing" in GHC's lexer to see how the state is pushed and popped).
I can't store any global data anywhere with Haskell
This is not true; in most cases something like the State monad is sufficient, but there is also the ST monad.
You don't need global state for this task, however. Writing a parser consists of two parts; lexical analysis and syntax analysis. The lexical analysis just turns a stream of characters into a stream of meaningful tokens. The syntax analysis turns tokens into an AST; this is where you should deal with indentation.
As you are interpreting the indentation, you will call a handler function as the indentation level changes -- when it increases (nesting), you call your handler function (perhaps with one arg incremented, if you want to track the indentation level); when the level decreases, you simply return the relevant AST portion from the function.
(As an aside, using a global variable for this is something that would not occur to me in an imperative language either -- if anything, it's an instance variable. The State monad is very similar conceptually to this.)
Finally, I think the phrase "I can't put all my lexing rules inside any monad" indicates some sort of misunderstanding of monads. If I needed to parse and keep global state, my code would look like:
data AST = ...
type Step = State Int AST
parseFunction :: Stream -> Step
parseFunction s = do
level <- get
...
if anotherFunction then put (level + 1) >> parseFunction ...
else parseWhatever
...
return node
parse :: Stream -> Step
parse s = do
if looksLikeFunction then parseFunction ...
main = runState parse 0 -- initial nesting of 0
Instead of combining function applications with (.) or ($), you combine them with (>>=) or (>>). Other than that, the algorithm is the same. (There is no "monad" to be "inside".)
Finally, you might like applicative functors:
eval :: Environment -> Node -> Evaluated
eval e (Constant x) = Evaluated x
eval e (Variable x) = Evaluated (lookup e x)
eval e (Function f x y) = (f <$> (`eval` x) <*> (`eval` y)) e
(or
eval e (Function f x y) = ((`eval` f) <*> (`eval` x) <*> (`eval` y)) e
if you have something like "funcall"... but I digress.)
There is plenty of literature on parsing with applicative functors, monads, and arrows; all of which have the potential to solve your problem. Read up on those and see what you get.
I wrote the follwing function:
let str2lst str =
let rec f s acc =
match s with
| "" -> acc
| _ -> f (s.Substring 1) (s.[0]::acc)
f str []
How can I know if the F# compiler turned it into a loop? Is there a way to find out without using Reflector (I have no experience with Reflector and I Don't know C#)?
Edit: Also, is it possible to write a tail recursive function without using an inner function, or is it necessary for the loop to reside in?
Also, Is there a function in F# std lib to run a given function a number of times, each time giving it the last output as input? Lets say I have a string, I want to run a function over the string then run it again over the resultant string and so on...
Unfortunately there is no trivial way.
It is not too hard to read the source code and use the types and determine whether something is a tail call by inspection (is it 'the last thing', and not in a 'try' block), but people second-guess themselves and make mistakes. There's no simple automated way (other than e.g. inspecting the generated code).
Of course, you can just try your function on a large piece of test data and see if it blows up or not.
The F# compiler will generate .tail IL instructions for all tail calls (unless the compiler flags to turn them off is used - used for when you want to keep stack frames for debugging), with the exception that directly tail-recursive functions will be optimized into loops. (EDIT: I think nowadays the F# compiler also fails to emit .tail in cases where it can prove there are no recursive loops through this call site; this is an optimization given that the .tail opcode is a little slower on many platforms.)
'tailcall' is a reserved keyword, with the idea that a future version of F# may allow you to write e.g.
tailcall func args
and then get a warning/error if it's not a tail call.
Only functions that are not naturally tail-recursive (and thus need an extra accumulator parameter) will 'force' you into the 'inner function' idiom.
Here's a code sample of what you asked:
let rec nTimes n f x =
if n = 0 then
x
else
nTimes (n-1) f (f x)
let r = nTimes 3 (fun s -> s ^ " is a rose") "A rose"
printfn "%s" r
I like the rule of thumb Paul Graham formulates in On Lisp: if there is work left to do, e.g. manipulating the recursive call output, then the call is not tail recursive.