The following code does not parse:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
print $ result
where result = last [1..1000000]
The compiler complains on the second print:
src/Main.hs:10:5: parse error on input `print'
Why is this?
The problem is that where clauses can be attached to bindings only, not to expressions.
In fact:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
is exactly equivalent to:
main :: IO ()
main = do
print $ result
where result = foldl' (+) 0 [1..1000000]
i.e. the where defines local definitions for main not for the print $ result line.
Since where must be the last part of a binding obviously the following print expression causes a syntax error.
To use a where inside a do-block you have to use it when defining the let bindings such as this (very silly example):
main = do
let result = f
where f = foldl' (+) 0 [1..1000000]
print result
You can check this in the grammar:
decl → gendecl
| (funlhs | pat) rhs
rhs → = exp [where decls]
| gdrhs [where decls]
Note that the where decls is part of the rhs rule which defines the right hand side of a declaration. If you check the rules for exp you wont find where mentioned:
exp → infixexp :: [context =>] type (expression type signature)
| infixexp
infixexp → lexp qop infixexp (infix operator application)
| - infixexp (prefix negation)
| lexp
lexp → \ apat1 … apatn -> exp (lambda abstraction, n ≥ 1)
| let decls in exp (let expression)
| if exp [;] then exp [;] else exp (conditional)
| case exp of { alts } (case expression)
| do { stmts } (do expression)
| fexp
fexp → [fexp] aexp (function application)
aexp → qvar (variable)
| gcon (general constructor)
| literal
| ( exp ) (parenthesized expression)
| ( exp1 , … , expk ) (tuple, k ≥ 2)
| [ exp1 , … , expk ] (list, k ≥ 1)
| [ exp1 [, exp2] .. [exp3] ] (arithmetic sequence)
| [ exp | qual1 , … , qualn ] (list comprehension, n ≥ 1)
| ( infixexp qop ) (left section)
| ( qop⟨-⟩ infixexp ) (right section)
| qcon { fbind1 , … , fbindn } (labeled construction, n ≥ 0)
| aexp⟨qcon⟩ { fbind1 , … , fbindn } (labeled update, n ≥ 1)
Related
I am new to Haskell and I am trying to calculate the maximum segment sum,
(#) :: Int -> Int -> Int
x # y = 0 `max` (x + y)
mss2 :: [Int] -> Int
mss2 = maximum . scanr (#) 0
The error is
No Modules Loaded for (#)
I found this snippet in Richard Bird's text.
What am I missing here?
Are there other ways to declare/overload the operators, is my approach wrong?
It appears that in the context of that book, (#) is being used as a stand-in for some binary operator such as (+) or (<>), even though this is not actually legal Haskell syntax†.
For questions about Haskell syntax, it’s helpful to consult the Haskell 2010 Report.
In Ch. 2 Lexical Structure, under §2.2 Lexical Program Structure, you can find # in the grammar of symbols that may appear in an operator name:
symbol → ascSymbol | uniSymbol⟨special | _ | " | '⟩
ascSymbol → ! | # | $ | % | & | ⋆ | + | . | / | < | = | > | ? | #
| \ | ^ | | | - | ~ | :
And §2.4 Lexical Structure: Identifiers and Operators defines valid operator names to include such symbols:
varsym → ( symbol⟨:⟩ {symbol} )⟨reservedop | dashes⟩
consym → ( : {symbol} )⟨reservedop⟩
However, the subscript in angle brackets denotes a “difference” or exclusion, so this disallows a list of reserved identifiers. Under the production reservedop you can find that # appears in that list:
reservedop → .. | : | :: | = | \ | | | <- | -> | # | ~ | =>
The reason is that the # symbol denotes an “as” pattern, described in §3.17.2.8 Informal Semantics of Pattern Matching:
Matching an as-pattern var#apat against a value v is the result of matching apat against v, augmented with the binding of var to v.
As patterns are very useful for controlling the sharing of values and making certain definitions more concise, e.g.:
-- | Merge two sorted lists.
merge :: (Ord a) => [a] -> [a] -> [a]
-- ‘as0’ & ‘bs0’ denote the original input lists.
-- ‘as’ & ‘bs’ denote their tails.
merge as0#(a : as) bs0#(b : bs) = case compare a b of
-- ‘as0’ passes along the same list cell;
-- repeating ‘a : as’ would allocate a /new/ cell.
GT -> b : merge as0 bs
_ -> a : merge as bs0
merge [] bs0 = bs0
merge as0 [] = as0
Therefore, the definition:
x # y = 0 `max` (x + y)
Or more conventionally written x#y = …, is equivalent to defining two variables referring to the same value, which furthermore is defined recursively:
x = 0 `max` (x + y)
y = x
Without the type signature Int -> Int -> Int, this definition would be accepted, defining x, y :: (Ord a, Num a) => a, but attempting to evaluate either variable would produce an infinite loop, since this is “unproductive” recursion.
The solution is to use a non-reserved symbol as your operator name instead, such as <#> or +..
† I can’t find a citation for this, but it’s possible that GHC used to accept this syntax, even though it was also disallowed by the Haskell 98 Report which was current at the time the first edition of this book came out, and that this example code just wasn’t updated for the second edition.
I'm writing a arithmetic parser to treat expressions like "1+2-3". I use this blog post as reference. To treat left associativity and precedence, I write a parser with Parsec according to this BNF (from blog post).
<exp> ::= <term> { ("+" | "-") <term> }
<term> ::= <factor> { ("*" | "/") <factor> }
<factor> ::= "(" <exp> ")" | <unary_op> <factor> | <int>
This is my parser code.
parseExp :: Parser Exp
parseExp = do
t1 <- parseTerm
loop t1
where termSuffix t1 = do
op <- lexeme $ oneOf "+-"
t2 <- parseTerm
case op of
'+' -> termSuffix (Binary Plus t1 t2)
'-' -> termSuffix (Binary Minus t1 t2)
loop t = termSuffix t <|> return t
parseTerm :: Parser Exp
parseTerm = do
f1 <- parseFactor
loop f1
where factorSuffix f1 = do
op <- lexeme $ oneOf "*/"
f2 <- parseFactor
case op of
'*' -> factorSuffix (Binary Mul f1 f2)
'/' -> factorSuffix (Binary Div f1 f2)
loop t = factorSuffix t <|> return t
parseFactor :: Parser Exp
parseFactor = parseConst <|> parseParen <|> parseUnary
parseParen = do
void $ lexeme $ char '('
e <- parseExp
void $ lexeme $ char ')'
return e
parseUnary :: Parser Exp
parseUnary = do
op <- lexeme $ oneOf "!~-"
f <- parseFactor
case op of
'!' -> return $ Unary LogNeg f
'~' -> return $ Unary BitCompl f
'-' -> return $ Unary ArithNeg f
parseConst :: Parser Exp
parseConst = do
i <- many1 digit
return (Const $ read i)
I also used this tutorial code as reference. tutorial
simpleExpr7 :: Parser SimpleExpr
simpleExpr7 = do
-- first parse a term
e <- term7
-- then see if it is followed by an '+ expr' suffix
maybeAddSuffix e
where
-- this function takes an expression, and parses a
-- '+ expr' suffix, returning an Add expression
-- it recursively calls itself via the maybeAddSuffix function
addSuffix e0 = do
void $ lexeme $ char '+'
e1 <- term7
maybeAddSuffix (Add e0 e1)
-- this is the wrapper for addSuffix, which adapts it so that if
-- addSuffix fails, it returns just the original expression
maybeAddSuffix e = addSuffix e <|> return e
My code doesn't work. This code works like this.
*Main CodeGen Parser> parseWithEof parseExp "-2"
Right (Unary ArithNeg (Const 2))
*Main CodeGen Parser> parseWithEof parseExp "(2)"
Right (Const 2)
*Main CodeGen Parser> parseWithEof parseExp "-!(((2)))"
Right (Unary ArithNeg (Unary LogNeg (Const 2)))
*Main CodeGen Parser> parseWithEof parseExp "1+2"
Left (line 1, column 4):
unexpected end of input
expecting digit
*Main CodeGen Parser> parseWithEof parseExp "1+2+3"
Left (line 1, column 6):
unexpected end of input
expecting digit
*Main CodeGen Parser> parseWithEof parseExp "1+2*3"
Left (line 1, column 6):
unexpected end of input
expecting digit
I can't understand why this results unexpected end of input.
Consider parsing 1+2. In parseExp this parses 1 into t1 = Const 1 and then enters the loop loop (Const 1). The loop tries the first alternative termSuffix (Const 1) which succesfully parses the operator +, the next term t2 = Const 2, and then loops back into termSuffix (Binary Plus (Const 1) (Const 2)) which expects either a + or -. The parse fails. Instead of looping back into termSuffix, you should loop back into loop to allow a single term after the first +:
parseExp :: Parser Exp
parseExp = do
t1 <- parseTerm
loop t1
where termSuffix t1 = do
op <- lexeme $ oneOf "+-"
t2 <- parseTerm
case op of
-- *** use `loop` here, not `termSuffix` ***
'+' -> loop (Binary Plus t1 t2)
'-' -> loop (Binary Minus t1 t2)
loop t = termSuffix t <|> return t
After making a similar change to parseTerm, your test cases all work fine.
I am trying to make a program that solves the tower of hanoi. I made it a bit complicated just for exercise:
hanoi :: [Int] -> String
hanoi n
| n > 0 = hanoi' n "1" "2" "3"
where hanoi' n a b c
| n == 0 = "|"
| otherwise = let pre = hanoi' (n-1) a c b
posle = hanoi' (n-1) b c a
in pre ++ a ++ " ~~> " ++ c ++ posle
| otherwise = "Number must be greater than 0!!!"
But i get:
hanoi.hs:7:97: parse error on input ‘=’
Can someone please explain to me what is going on? I see now that i don't understand an important part of the language.
Your where has to come after all guards.
hanoi :: [Int] -> String
hanoi n
| n > 0 = hanoi' n "1" "2" "3"
| otherwise = "Number must be greater than 0!!!"
where hanoi' n a b c
| n == 0 = "|"
| otherwise = let pre = hanoi' (n-1) a c b
posle = hanoi' (n-1) b c a
in pre ++ a ++ " ~~> " ++ c ++ posle
This is stated in 4.4.3, although it's somewhat hidden if you're not used to BNF-like syntax:
decl → (funlhs | pat) rhs
funlhs → var apat { apat }
| pat varop pat
| ( funlhs ) apat { apat }
rhs → = exp [where decls]
| gdrhs [where decls]
gdrhs → guards = exp [gdrhs]
guards → | guard1, …, guardn (n ≥ 1)
guard → pat <- infixexp (pattern guard)
| let decls (local declaration)
| infixexp (boolean guard)
rhs is the important token. It's the only part that contains the optional where. A guard may only contain expressions and be followed by other guards.
When i compile my code in ghci, there is no problem. It can compile correctly. However, if i try to compile it in hugs, I get the error "compiled code too complex". I think the problem is due to many | conditions.
If I change it to use if/else, there is no problem. I can add if/else statements 100 times but this will be very tiresome and annoying. Rather than that, I tried to put if/else statements after 20-30 | conditions, but i cannot make | work inside if statements like the below:
f x y z
| cond1 = e1
| cond2 = e2
...
if (1)
then
| cond30 = e30
| cond31 = e31
...
else
| cond61 = e61
| cond62 = e62
How can I fix the code with the least effort? The complete code is on hpaste because it is longer than StackOverflow's question size limit.
Avoiding repetitive guards
Firstly, you can rewrite
function input
| this && that && third thing && something else = ... -- you only actually needed brackets for (head xs)
| this && that && third thing && something different = ....
| this && that && a change && ...
...
| notthis && ....
with
function input | this = function2 input'
| notthis = function4 input'
function2 input | that = function3 input''
| notthat = ...
That should simplify your 200 lines of copo code down, but it's still the wrong approach.
Use a function to deal with the same problem just once, not every time
The 4 cases for dealing with operations that you deal with time after time could be replaced with one function, perhaps like:
operation :: Num a => Char -> a -> a -> a
operation x = case x of
'+' -> (+)
'-' -> (-)
'*' -> (*)
'/' -> (/)
_ -> error ("operation: expected an operation (+-*/) but got " ++ [c])
Use list functions instead of testing characters one at a time
You should use some standard functions to help reduce all the single character checks into just grabbing as much number as is there. takeWhile :: (a -> Bool) -> [a] -> [a], so
takeWhile isDigit "354*243" = "354"
takeWhile isDigit "+245" = ""
and there's the corresponding dropWhile:
dropWhile isDigit "354*1111" = "*1111"
dropWhile isDigit "*1111" = "*1111"
So the most dramatic shortening of your code would be to start copo with
copo xs = let
numText = takeWhile isDigit xs
theRest = droWhile isDigit xs
num = read numText
....
in answer....
but there's a shortcut if you want both takeWhile and dropWhile, called span, because span p xs == (takeWhile p xs, dropWhile p xs)
copo xs = let
(numText,theRest) = span isDigit xs
num = read numText
....
in answer....
Use recursion instead of repeating code
You deal with 234 then 234*56 then 234*56/23 then ....
You could replace this with a recursive call to copo, or produce a tree. This depends on whether you're supposed to obey the normal operator precedence (* or / before + or -) or not.
If you insist on guards, instead of
foo a b c d
| cond1, cond2, cond3 = ...
| cond1, cond2, cond4 = ...
| cond5, cond6, cond7 = ...
| cond5, cond6, cond8 = ...
write
foo a b c d
| cond1, cond2 = case () of
() | cond3 = ...
| cond4 = ...
| cond5, cond6 = case () of
() | cond7 = ...
| cond8 = ...
Help me translate following block of the Haskell code. The run function produces text string that corresponding to a given regex that abstracted as Pattern.
Declaration of the type Pattern you can see below in the block of F# code. You can test run function like
genex $ POr [PConcat [PEscape( DoPa 1) 'd'], PConcat [PEscape (DoPa 2) 'd']]
{-# LANGUAGE RecordWildCards, NamedFieldPuns #-}
import qualified Data.Text as T
import qualified Control.Monad.Stream as Stream
import Text.Regex.TDFA.Pattern
import Control.Monad.State
import Control.Applicative
genex = Stream.toList . run
maxRepeat :: Int
maxRepeat = 3
each = foldl1 (<|>) . map return
run :: Pattern -> Stream.Stream T.Text
run p = case p of
PBound low high p -> do
n <- each [low..maybe (low+maxRepeat) id high]
fmap T.concat . sequence $ replicate n (run p)
PConcat ps -> fmap T.concat . Stream.suspended . sequence $ map run ps
POr xs -> foldl1 mplus $ map run xs
PEscape {..} -> case getPatternChar of
'd' -> chars $ ['0'..'9']
'w' -> chars $ ['0'..'9'] ++ '_' : ['a'..'z'] ++ ['A'..'Z']
ch -> isChar ch
_ -> error $ show p
where
isChar = return . T.singleton
chars = each . map T.singleton
Below I give my poor attempt. It works but incorrectly. The problem is in the following.
Let assume parse produces Pattern like that
parse "\\d\\d";;
val it : Pattern = POr [PConcat [PEscape (DoPa 1,'d'); PEscape (DoPa 2,'d')]]
and
parse "\\d{2}";;
val it : Pattern = POr [PConcat [PBound (2,Some 2,PEscape (DoPa 1,'d'))]]
So feeding both patterns to run I expect to receive seq [['2'; '2']; ['2'; '3']; ['2'; '1']; ['2'; '4']; ...] that corresponding to seq ["22"; "23"; "21"; "24"; ...] (2 symbols per string)
This is valid in the first case,
POr [PConcat [PEscape (DoPa 1,'d'); PEscape (DoPa 2,'d')]] |> run;;
val it : seq = seq [['2'; '2']; ['2'; '3']; ['2'; '1']; ['2'; '4']; ...]
seq ["22"; "23"; "21"; "24"; ...]
but not in the second
POr [PConcat [PBound (2,Some 2,PEscape (DoPa 1,'d'))]] |> run;;
val it : seq = seq [['2']; ['2']; ['2']; ['3']; ...]
seq ["2"; "2", "2"; "3", "2"; "1", "2"; "4";...] (1 symbol per string)
I tested different variants with the following clauses:
| POr ps -> Seq.concat (List.map run ps)
| PConcat ps -> (sequence (List.map (run >> Seq.concat) ps))
| PBound (low,high,p) ->
but all in vain. I can't figure out the valid translation.
-Maybe I should use String or Array instead of char list.
-And I assume that Seq is quite good analogue to Control.Monad.Stream. Is it right?
Thanks in advance for help
open System
/// Used to track elements of the pattern that accept characters or are anchors
type DoPa = DoPa of int
/// Pattern is the type returned by the regular expression parser.
/// This is consumed by the CorePattern module and the tender leaves
/// are nibbled by the TNFA module.
type Pattern = PEmpty
| POr of Pattern list // flattened by starTrans
| PConcat of Pattern list // flattened by starTrans
| PBound of int * (int option) * Pattern // eliminated by starTrans
| PEscape of DoPa * char // Backslashed Character
let maxRepeat = 3
let maybe deflt f opt =
match opt with
| None -> deflt
| Some v -> f v
/// Cartesian production
/// try in F# interactive: sequence [[1;2];[3;4]];;
let rec sequence = function
| [] -> Seq.singleton []
| (l::ls) -> seq { for x in l do for xs in sequence ls do yield (x::xs) }
let from'space'to'tilda = [' '..'~'] |> List.ofSeq
let numbers = ['0'..'9'] |> List.ofSeq
let numbers'and'alphas = (['0'..'9'] # '_' :: ['a'..'z'] # ['A'..'Z']) |> List.ofSeq
let whites = ['\009'; '\010'; '\012'; '\013'; '\032' ] |> List.ofSeq
let rec run (p:Pattern) : seq<char list> =
let chars chs = seq { yield [for s in chs -> s] }
match p with
| POr ps -> Seq.concat (List.map run ps)
| PConcat ps -> (sequence (List.map (run >> Seq.concat) ps))
| PBound (low,high,p) ->
let ns = seq {low .. maybe (low + maxRepeat) id high}
Seq.concat (seq { for n in ns do yield sequence (List.replicate n (((run >> Seq.concat) p))) })
// Seq.concat (seq { for n in ns do yield ((List.replicate n (run p)) |> Seq.concat |> List.ofSeq |> sequence)})
//((List.replicate low (run p)) |> Seq.concat |> List.ofSeq |> sequence)
// PConcat [ for n in ns -> p] |> run
| PEscape(_, ch) ->
match ch with
| 'd' -> chars numbers
| 'w' -> chars numbers'and'alphas
| ch -> chars [ch]
| _ -> Seq.empty
I don't know why you didn't translate Data.Text from Haskell to string in F#, you just need to mimic two functions. Apart from that I did just a few changes to make it work, this way you can compare it easily with your original code, see replaced code between (* *)
open System
// Mimic Data.Text as T
module T =
let concat (x:seq<_>) = System.String.Concat x
let singleton (x:char) = string x
/// Used to track elements of the pattern that accept characters or are anchors
type DoPa = DoPa of int
/// Pattern is the type returned by the regular expression parser.
/// This is consumed by the CorePattern module and the tender leaves
/// are nibbled by the TNFA module.
type Pattern = PEmpty
| POr of Pattern list // flattened by starTrans
| PConcat of Pattern list // flattened by starTrans
| PBound of int * (int option) * Pattern // eliminated by starTrans
| PEscape of DoPa * char // Backslashed Character
let maxRepeat = 3
let maybe deflt f opt =
match opt with
| None -> deflt
| Some v -> f v
/// Cartesian production
/// try in F# interactive: sequence [[1;2];[3;4]];;
let rec sequence = function
| [] -> Seq.singleton []
| (l::ls) -> seq { for x in l do for xs in sequence ls do yield (x::xs) }
let from'space'to'tilda = [' '..'~'] |> List.ofSeq
let numbers = ['0'..'9'] |> List.ofSeq
let numbers'and'alphas = (['0'..'9'] # '_' :: ['a'..'z'] # ['A'..'Z']) |> List.ofSeq
let whites = ['\009'; '\010'; '\012'; '\013'; '\032' ] |> List.ofSeq
let rec run (p:Pattern) (*: seq<char list> *) =
(* let chars chs = seq { yield [for s in chs -> s] } *)
let chars (chs:seq<char>) = Seq.map string chs
match p with
| POr ps -> Seq.concat (List.map run ps)
| PConcat ps -> Seq.map T.concat << sequence <| List.map run ps (* (sequence (List.map (run >> Seq.concat) ps)) *)
| PBound (low,high,p) ->
seq {
for n in [low..maybe (low+maxRepeat) id high] do
yield! ( (Seq.map T.concat << sequence) (List.replicate n (run p)) )}
(*let ns = seq {low .. maybe (low + maxRepeat) id high}
Seq.concat (seq { for n in ns do yield sequence (List.replicate n (((run >> Seq.concat) p))) *)
// Seq.concat (seq { for n in ns do yield ((List.replicate n (run p)) |> Seq.concat |> List.ofSeq |> sequence)})
//((List.replicate low (run p)) |> Seq.concat |> List.ofSeq |> sequence)
// PConcat [ for n in ns -> p] |> run
| PEscape(_, ch) ->
match ch with
| 'd' -> chars numbers
| 'w' -> chars numbers'and'alphas
| ch -> chars [ch]
| _ -> Seq.empty
UPDATE
If you are translating Haskell code to F# you may try using this code which mimics many Haskell functions, including those using Type Classes.
I did a test translating as close as possible to your original Haskell code but using F# List (not lazy) and looks like this:
#load "Prelude.fs"
#load "Monad.fs"
#load "Applicative.fs"
#load "Monoid.fs"
open Prelude
open Control.Monad.Base
open Control.Applicative
module T =
let concat (x:list<_>) = System.String.Concat x
let singleton (x:char) = string x
type DoPa = DoPa of int
type Pattern = PEmpty
| POr of Pattern list
| PConcat of Pattern list
| PBound of int * (int option) * Pattern
| PEscape of DoPa * char
let maxRepeat = 3
let inline each x = foldl1 (<|>) << map return' <| x
let rec run p:list<_> =
let inline isChar x = return' << T.singleton <| x
let inline chars x = each << map T.singleton <| x
match p with
| PBound (low,high,p) -> do' {
let! n = each [low..maybe (low+maxRepeat) id high]
return! (fmap T.concat << sequence <| replicate n (run p))}
| PConcat ps -> fmap T.concat << sequence <| map run ps
| POr xs -> foldl1 mplus <| map run xs
| PEscape (_, ch) ->
match ch with
| 'd' -> chars <| ['0'..'9']
| 'w' -> chars <| ['0'..'9'] # '_' :: ['a'..'z'] # ['A'..'Z']
| ch -> isChar ch
| _ -> failwith <| string p
let genex = run