| Safe Haskell | Safe-Inferred |
|---|
Lessons.Lesson04
Description
Notes taken by Ugnė Pacevičiūtė
Synopsis
- add :: Int -> Int -> Int
- sumOfInts :: [Int] -> Int
- mapping :: (a -> b) -> [a] -> [b]
- safeDivision :: Integer -> Integer -> Either String Integer
- type ErrorMsg = String
- type Parser a = String -> Either ErrorMsg (a, String)
- parseLetter :: Parser Char
- parseDigit :: Parser Char
- many :: Parser a -> Parser [a]
- many1 :: Parser a -> Parser [a]
- parseString :: Parser String
- pmap :: (a -> b) -> Parser a -> Parser b
- parseInteger :: Parser Integer
Documentation
add :: Int -> Int -> Int Source #
The add function takes two integers and returns their sum.
It is a simple example of a named function definition.
sumOfInts :: [Int] -> Int Source #
Anonymous functions (and one of their implementations - lambda functions) are functions without a name. In Haskell, they are written using a backslash `\`, followed by their parameters.
The function below demonstrates how foldl can be used with both named and anonymous functions.
foldl stands for fold left, meaning it combines all elements of a list using a binary function.
>>>foldl add 0 [1,2,3,4,5]15
>>>foldl add 0 []0
>>>foldl add (-1) []-1
>>>foldl (\a b -> a * b) 1 [1,2,3,4]24
mapping :: (a -> b) -> [a] -> [b] Source #
In this example, t represents the tail of a list — that is, all elements except the first.
This function shows how to apply a given function f to every element in the list.
It is essentially a reimplementation of Haskell’s built-in map function.
safeDivision :: Integer -> Integer -> Either String Integer Source #
The Either type is used to represent computations that can return one of two possible results — typically an error (Left) or a success (Right).
This function safely performs integer division. If the divisor is zero, it returns an error message wrapped in Left. Otherwise, it returns the result in Right.
>>>safeDivision 1 0Left "Division by zero"
>>>safeDivision 1 10Right 0
type ErrorMsg = String Source #
The type 'Parser a' represents a function that takes a string and tries to extract a value of type a from its beginning.
It returns either:
Left with an error message, or
Right with a tuple (a, String) — the parsed value and the remaining input.
parseLetter :: Parser Char Source #
This parser tries to read a single alphabetic letter from the beginning of a string.
If the input is empty, it fails with an error message. If the first character is a letter, it returns it along with the rest of the string. Otherwise, it returns an error describing what went wrong.
The operator $ allows us to avoid parentheses for function application.
>>>parseLetter "fksdjhfdjk"Right ('f',"ksdjhfdjk")
>>>parseLetter ""Left "A letter is expected but got empty input"
>>>parseLetter "3213fksdjhfdjk"Left "A letter is expected, but got 3"
parseDigit :: Parser Char Source #
This parser works similarly to parseLetter, but it checks for digits.
>>>parseDigit "ghfjkd"Left "A digit is expected, but got g"
>>>parseDigit "55ghfjkd"Right ('5',"5ghfjkd")
many :: Parser a -> Parser [a] Source #
The many parser runs another parser repeatedly on the input.
It succeeds even if the inner parser matches zero times.
The helper function many' carries an accumulator acc that collects results.
v represents the value returned by the inner parser and r represents the remaining input string after parsing.
parseString :: Parser String Source #
This parser combines everything we have built so far. It parses one or more letters from the beginning of the input string. It succeeds if at least one letter is found, and returns the collected string.
>>>parseString "afds"Right ("afds","")
>>>parseString "afds5345"Right ("afds","5345")
>>>parseString "afds 5345"Right ("afds"," 5345")
pmap :: (a -> b) -> Parser a -> Parser b Source #
The pmap function allows us to transform the result produced by a parser without changing how that parser actually reads the input string.
A parser of type 'Parser a' returns either:
Left with an error message if parsing fails, or
'Right (v, r)' where v is the parsed value and r is the remaining input.
pmap takes a transformation function f :: a -> b and a parser p :: Parser a,
and produces a new parser Parser b that behaves just like p but applies f
to the successfully parsed value before returning it.
The overall structure of the result (Left or Right, plus the remaining input)
stays exactly the same — only the parsed value itself is modified.
For example, if many1 parseDigit returns Right ("123", ""),
then pmap read (many1 parseDigit) will return Right (123, "").
This pattern is the same idea as map for Lists: map over the value
inside a container (in this case, the parsing context).
parseInteger :: Parser Integer Source #
This parser reads one or more digits from the input string and converts them into an Integer.
It demonstrates how to combine parsing ('many1 parseDigit') with transformation ('pmap read').
>>>parseInteger "3423432gfhg"Right (3423432,"gfhg")