Commit 3fd92c3c authored by Sandra Dylus's avatar Sandra Dylus
Browse files

Add master solutions for exercise 2

parent 8074894b
> {-# LANGUAGE GADTSyntax #-}
> module Functional.Exercise.Exercise2 where
>
> import qualified Functional.Lecture.DataAndFunctions as Data
> import qualified Functional.Lecture.MoreData as Data
> import Functional.Lecture.FunctionDefinitions
We implemented the following type synonym for a `Integer`-bound.
type Bounds = (Integer,Integer)
1) Implement a function `moveWithinBounds` that yields a coordinate based on a given bound, direction and coordinate. The new coordinate changes by one unit (that is, plus 1 or minus 1) from the given coordinate in the y-component (or x-component) with respect to the given direction. If the resulting change in that component does not adhere with the given bounds, the new coordinate is identical to the given one.
> moveWithinBounds :: Data.Bounds -> Data.Bounds -> Data.Direction -> Data.Coordinate -> Data.Coordinate
> moveWithinBounds xBounds yBounds dir coords =
> if Data.xCoord newCoords `Data.inBounds` xBounds && Data.yCoord newCoords `Data.inBounds` yBounds
> then newCoords
> else coords
> where newCoords = Data.moveByDirection dir coords
2) Evaluate the following expression step-by-step, specifying the demanded argument as well as the applied rule as done in the lecture, for the constant function `boolEx4`.
```
boolEx4 = False && (True || True)
```
boolEx4
^^^^^^^
= { definition of `boolEx4`}
False && (True || True)
^^^^^^^^^^^^^^^^^^^^^^^
= { definition for `(&&)`: second rule without binding any variables }
False
3) Consider the following `Bool`ean expressions in Haskell. Note that the operator `(==>)` is defined in the lecture notes.
a) True || False && True ==> not False
b) False ==> True ==> True
c) False && True ==> True || False ==> True || not False
A) Give the fully parenthesised versions of the following `Bool`ean expressions in Haskell with respect to their precedences.
a) (True || (False && True)) ==> (not False)
b) False ==> (True ==> True)
c) (False && True) ==> ((True || False) ==> (True || (not False)))
B) Give the prefix version for each expression: that is, execlusively use the prefix notation for function applications.
a) (==>) ((||) True ((&&) False True)) (not False)
b) (==>) False ((==>) True True)
c) (==>) ((&&) False True) ((==>) ((||) True False) ((||) True (not False)))
4) Given the following definition of an implication on Boolean values as well as a non-terminating constant `boolLoop`
```
impl :: Bool -> Bool -> Bool
impl True True = True
impl True False = False
impl False _ = True
boolLoop :: Bool
boolLoop = boolLoop
```
which of the following expression will terminate, which of them won't? Try to explain why this is the case.
a) impl (impl (False && True) False) boolLoop
b) boolLoop ==> True
c) False ==> boolLoop
a) won't terminate: first parameter evaluates to `True` and therefore the second argument needs to be evaluated
b) won't terminate: first argument needs to be evaluated
c) terminates: `imp` does not evaluate its second argument if the first argument is `False`
Can you give an alternative implementation (or choose one from the lecture) that will terminate for one of the example that won't terminate for `impl`?
```
impl :: Bool -> Bool -> Bool
impl True x = x
impl False_ = True
```
Using this version of the implementation example a) terminates.
```
impl :: Bool -> Bool -> Bool
impl _ True = True
impl x False = not x
```
With this version of `impl`, example b) terminates.
<<<------------- Exercises corresponding to lecture on 9/12/19 ------------->>>
First we define a data type for `Token`s as follows.
> data Token where
> Blank :: Token
> Block :: Token
Consider now the following data type that is a list-like structure like we have seen for `CoordMap` but for `Token`.
> data Row where
> EmptyR :: Row
> ARow :: Token -> Row -> Row
5) Implement a function `prettyRow` that prints each `Token` of the row seperated by one whitespace.
> prettyRow EmptyR = ""
> prettyRow (ARow t rs) = prettyToken t ++ " " ++ prettyRow rs
> where
> prettyToken Blank = " "
> prettyToken Block = "#"
On top of these rows, we define a data type `Field` that consists of none or several `Row`s.
> data Field where
> EmptyF :: Field
> AField :: Row -> Field -> Field
6) Next we want to implement a function that replaces all `Token` that match the first argument with a `Blank`.
Define this functionality for `Row` first and then for `Field`; reuse the function for `Row` for the latter!
> replaceTokenInRow :: Token -> Row -> Row
> replaceTokenInRow t EmptyR = EmptyR
> replaceTokenInRow t (ARow _ row) = ARow t (replaceTokenInRow t row)
> replaceTokenInField :: Token -> Field -> Field
> replaceTokenInField t EmptyF = EmptyF
> replaceTokenInField t (AField row field) = AField (replaceTokenInRow t row) (replaceTokenInField t field)
7) Last but not least, we want to implement a function to check if a field has a given token.
> hasToken :: Token -> Field -> Bool
> hasToken t EmptyF = False
> hasToken t (AField row field) = hasTokenRow row || hasToken t field
> where
> hasTokenRow EmptyR = False
> hasTokenRow (ARow tok row) = eqToken t tok || hasTokenRow row
>
> eqToken :: Token -> Token -> Bool
> eqToken Blank Blank = True
> eqToken Block Block = True
> eqToken _ _ = False
6) Implement a function `prettyField` that prints each `Row` of the field in one line seperated by one whitespace,
and the columns seperated by newlines.
> prettyField :: Field -> String
> prettyField EmptyF = ""
> prettyField (AField rs f) = prettyRow rs ++ "\n" ++ prettyField f
7) Last but not least, we want to implement a function that generates a field with respect to the given bounds
for the x- as well as y-axis; all positions should be filled with the given token.
> fieldWithBounds :: Data.Bounds -> Data.Bounds -> Token -> Field
> fieldWithBounds (minX, maxX) (minY, maxY) t =
> repColumn (maxY - minY) (repRow (maxX - minX) t)
> where
> repColumn :: Integer -> Row -> Field
> repColumn 0 v = EmptyF
> repColumn n v = AField v (repColumn (n-1) v)
> repRow :: Integer -> Token -> Row
> repRow 0 v = EmptyR
> repRow n v = ARow v (repRow (n-1) v)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment