Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:2025:l11 [2025/05/18 13:01]
cata_chiru
pp:2025:l11 [2025/05/18 13:35] (current)
cata_chiru [11.3. Nice to read]
Line 97: Line 97:
 Applicates, as monads, are used preponderantly for type construction and validation. Applicates, as monads, are used preponderantly for type construction and validation.
  
-1. For the first task we will want to validate a database of users.+5. For the first task we will want to validate a database of users.
  
 Being given the following data types: Being given the following data types:
Line 114: Line 114:
 </​code>​ </​code>​
  
-1.1. Create the instance of Applicative for Validation.+5.1. Create the instance of Applicative for Validation.
  
-1.2. Create functions to validate each attribute of a user.+5.2. Create functions to validate each attribute of a user.
  
 <code haskell> <code haskell>
Line 130: Line 130:
 Balance can also be negative. Balance can also be negative.
  
-1.3. Make use of the above functions, and the functions from Applicative,​ as well as infixed fmap ''​(<​$>​)''​ to create a validation function for the user.+5.3. Make use of the above functions, and the functions from Applicative,​ as well as infixed fmap ''​(<​$>​)''​ to create a validation function for the user.
  
 <code haskell> <code haskell>
Line 136: Line 136:
 </​code>​ </​code>​
  
-1.4 Create unpackUser that takes a tuple and returns a User:+5.4 Create unpackUser that takes a tuple and returns a User:
  
 <code haskell> <code haskell>
Line 142: Line 142:
 </​code>​ </​code>​
  
-1.5 Being given the following list of user data:+5.5 Being given the following list of user data:
  
 <code haskell> <code haskell>
Line 156: Line 156:
 </​code>​ </​code>​
  
-1.6 Filter the users with a negative balance.+5.6 Filter the users with a negative balance.
  
 <code haskell> <code haskell>
 filter_debtors :: BankAccount -> BankAccount filter_debtors :: BankAccount -> BankAccount
 +</​code>​
 +
 +6. Recall what a parser is from the course lecture:
 +
 +<code haskell>
 +import Data.Char
 +import Control.Applicative
 +
 +data Expr = Var String | Val Int | Plus Expr Expr deriving Show
 +
 +data Parser a = Parser (String -> [(a,​String)])
 +
 +parse (Parser p) s = p s
 +
 +instance Monad Parser where
 +--    (>>=) :: Parser a -> (a -> Parser b) -> Parser b 
 +    mp >>= f = Parser $ \s ->
 +                case parse mp s of
 +                     [] -> []
 +                     ​[(v,​r)] -> parse (f v) r
 +    return x = Parser $ \s -> [(x,s)]
 +
 +instance Applicative Parser where
 +    af <*> mp = 
 +        do 
 +            f <- af
 +            v <- mp
 +            return $ f v
 +    pure = return
 +
 +instance Functor Parser where 
 +    fmap  f mp = 
 +        do 
 +            x <- mp
 +            return $ f x
 +
 +
 +charParser :: Char -> Parser Char
 +charParser c = Parser $ \s -> 
 +                case s of 
 +                    [] -> []
 +                    (x:xs) -> if (x == c) then [(x,xs)] else []
 +
 +predicateParser :: (Char -> Bool) -> Parser Char
 +predicateParser p = Parser $ \s ->
 +                        case s of
 +                            [] -> []
 +                            (x:xs) -> if p x then [(x,xs)] else []
 +
 +
 +
 +</​code>​
 +
 +6.1 Try to understand and reimplement the instances for Functor, Applicative and Monad for Parser yourself.
 +
 +6.2 Using the definitions above and functions from Data.Char [5], implement letter - that parses one letter of the input, and digit - that parses one digit (given as a char) of the input.
 +
 +<code haskell>
 +letter :: Parser Char
 +letter = undefined
 +
 +digit :: Parser Char
 +digit = undefined
 +</​code>​
 +
 +6.3 Use letter, digit and functions from the classes studied in this laboratory to define letterDigit that parses one letter and one digit one after the other:
 +
 +<code haskell>
 +letterDigit :: Parser (Char,Char)
 +letterDigit = undefined
 +
 +positive_parse_ex = parse letterDigit "​a1b2c3"​ -- by calling this in the command line we should get [(('​a','​1'​),"​b2c3"​)]
 +negative_parse_ex = parse letterDigit "​aa2a"​ -- by calling this in the command line we should get []
 </​code>​ </​code>​
  
Line 173: Line 246:
 4. https://​www.youtube.com/​watch?​v=FLAPIgvlVnE&​t=1945s&​ab_channel=JamesHobson 4. https://​www.youtube.com/​watch?​v=FLAPIgvlVnE&​t=1945s&​ab_channel=JamesHobson
  
 +5. [Data.Char Library](https://​hackage.haskell.org/​package/​base-4.21.0.0/​docs/​Data-Char.html)