How can I skip spaces when parsing a haskell string [closed] - parsing

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have the following definition in a parser using the Haskell ReadP library:
expr = chainl1 comp (string "===" >> return fun6)
How can I skip spaces before the === operator? I don't know how to include it in this syntax.

ReadP has skipSpaces for exactly that usecase; your parser then becomes
expr = chainl1 comp (skipSpaces >> string "===" >> return fun6)

Related

Should variables and strings be treated differently in constructing a language? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm currently working on a language and have come to an issue regarding variable declarations in that to check what value a variable is in the REPL, I must use quotation marks.
> x := 1
> "x"
1
The desired behaviour however would be the following:
> x := 1
> x
1
I have defined my ADT in the following way:
data S = Integer Integer | String String | Assign String S | Expr Add [S]
I can parse everything correctly.
parseString :: Parser HVal
parseString = char '"' *> many1 (noneOf "\"") <* char '"' >>= (return . String)
parseAssign :: Parser HVal
parseAssign = do
var <- many1 letter
spaces
string ":="
spaces
val <- try (parsersHVal)
spaces
return $ Assign var val
I think however that the problem is done to the evaluation functions.
evalHVal :: Env -> HVal -> IOThrowsError HVal
evalHVal env val#(Integer _) = return $ val
evalHVal env val#(String _) = return $ val
evalHVal env (String val) = getVar env val >>= \var -> evalHVal env var
If I keep the first line that evaluates a string, the following occurs in the REPL and I receive a warning that the second line is redundant:
> x := 1
> "x"
'x'
If I keep the second line however I get the behaviour as described from the beginning.
In both cases, quotations around the variable have to be placed in order to evaluate it. I recongise though that I use many1 letter rather than parseString in the function parseAssign. I have tried changing this to parseString but I obtain the same behaviour.
What confuses me the most however is that since everything is read in as a string, then why doesn't many1 letter require quotations in parseAssign like how parseString requires? I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.
Should variables and strings be treated differently in constructing a language?
Yes
data S = ...
Should be:
data S = ... | Var String
What confuses me the most however is that since everything is read in as a string, then why doesn't many1 letter require quotations in parseAssign like how parseString requires?
That should be obvious. See the definition:
parseString = char '"' *> ...
The very first part of parseString clearly looks to parse char '"'.
The definition of parseAssign does not look for ".
I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.
Well " is not a letter so it shouldn't/wouldn't allow for a quotation mark. More, it wouldn't "assign", whatever that verb means, because it lacks the Assign constructor along with all the other critical parts of parseAssign.
Variables and strings should be considered differently. Although they're both strings in the source language, they cannot be treated identically as they are distinct within the data model of the language.

F# Idiomatic Index plus one when printing an index [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Is there a more idiomatic way to print an index +1 value with F#?
let plusOne i = i + 1
let collection = [1..10]
collection |> List.iteri (fun index value -> printfn "%i %i" (plusOne index) value)
F# does have many special idioms but that doesn’t mean it breaks the very common idiom in which indices of list/array... start from zero.
So, to answer to question: no, F# does not have any special idiom for index plus.
However, if you are intending to often iter a list with index plus one, you can use Active Pattern to implicitly increase the index right in the parameter declaration, like this:
let (|Inc|) = (+) 1
let collection = [1..10]
collection |> List.iteri (fun (Inc i) value -> printfn "%i %i" i value)

F# command line (fsi) doesn't recognize function, compile error, why? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I tried F# under command line, it doesn't recognize function definition
> let ref f n=
- if(n<=2)then 1
- else f(n-1)+f(n-2)
- ;;
val ref : f:(int -> int) -> n:int -> int
> printf "%i" (f 10)
- ;;
printf "%i" (f 10)
-------------^
stdin(9,14): error FS0039: The value or constructor 'f' is not defined
Question: any error in my program? I copied and pasted the definition and usage of f into visual studio's F# project, it runs OK.
But Why command line fails?
You defined a function named ref, but you're trying to call a function named f. No such function was defined (though your ref function takes a parameter named f), so you can't call it.
You probably intended to define a recursive function f using the rec keyword (with a 'c'), rather than defining a function named ref.
I copied and pasted the definition and usage of f into visual studio's F# project, it runs OK.
That's only possible if your VS project already contains a definition of a function named f.

Fail to currying F# printf function [duplicate]

This question already has answers here:
How to define printfn equivalent in F#
(2 answers)
Currying functions with format dependent types
(1 answer)
Closed 8 years ago.
I was trying to do the following:
let print = printf "%A"
print "Test"
print [1..10]
I got an error says the print function is expecting a string thus doesn't take [1..10]. Why doesn't this work?

Debugging Haskell read function

I'm new to Haskell and I'm writing a simple AI decision system to play a 20 questions style of game. If the program is unable to guess the correct answer, it will ask for a question to use to distinguish the answer and it will store that question in a tree. It reads the tree in from the file system at the start of the program and writes it back out at the end.
I'm having a lot of problems with the serialization code in Haskell. I'm getting the error "Prelude read: no parse". What's going on? Here's my code:
import Data.Char
import System.IO
-- Defines a type for a binary tree that holds the questions and answers
data Tree a =
Answer String |
Question String (Tree a) (Tree a)
deriving (Read, Show)
-- Starts the game running
main = do
let filePath = "data.txt"
fileContents <- readFile filePath
animals <- return (read fileContents)
putStrLn "Think of an animal. Hit Enter when you are ready. "
_ <- getLine
ask animals
writeFile filePath (show animals)
-- Walks through the animals tree and ask the question at each node
ask :: Tree a -> IO ()
ask (Question q yes no) = do
putStrLn q
answer <- getLine
if answer == "yes" then ask yes
else ask no
ask (Answer a) = do
putStrLn $ "I know! Is your animal a " ++ a ++ "?"
answer <- getLine
if answer == "yes" then computerWins
else playerWins
computerWins = do putStrLn "See? Humans should work, computers should think!"
playerWins = do putStrLn "TODO"
And here's the data file I'm using:
Question "Does it live in the water?"
((Question "Does it hop?") (Answer "frog") (Answer "fish"))
(Answer "cow")
read is not intended to handle things like extra parentheses robustly. Your code works for me with the following data file:
Question "Does it live in the water?"
(Question "Does it hop?" (Answer "frog") (Answer "fish"))
(Answer "cow")

Resources