Skip to content

Commit

Permalink
State exercise
Browse files Browse the repository at this point in the history
  • Loading branch information
tonymorris committed Nov 7, 2012
1 parent bd944d4 commit ad7ffde
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .ghci
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
:m + Test.QuickCheck
:set prompt ">> "
:set -Wall
:set -fno-warn-unused-imports
:set -fno-warn-unused-binds

1 change: 1 addition & 0 deletions course.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Library
L02.List
L03.Fluffy
L03.Misty
L03.State
L04.Testing
L05.Person
L05.Parser
Expand Down
2 changes: 2 additions & 0 deletions src/Course.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Course
, module L02.List
, module L03.Fluffy
, module L03.Misty
, module L03.State
, module L04.Testing
, module L05.Person
, module L05.Parser
Expand All @@ -24,6 +25,7 @@ import L01.Validation
import L02.List
import L03.Fluffy
import L03.Misty
import L03.State
import L04.Testing hiding (tests)
import L05.Person
import L05.Parser
Expand Down
164 changes: 164 additions & 0 deletions src/L03/State.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}

module L03.State where

import L01.Optional
import L02.List
import L03.Fluffy
import L03.Misty
import Data.Char
import qualified Data.Set as S
import qualified Data.Foldable as F

-- A `State` is a function from a state value `s` to (a produced value `a`, and a resulting state `s`).
newtype State s a =
State {
runState ::
s
-> (a, s)
}

-- Exercise 1
-- Relative Difficulty: 2
-- Implement the `Fluffy` instance for `State s`.
instance Fluffy (State s) where
furry =
error "todo"

-- Exercise 2
-- Relative Difficulty: 3
-- Implement the `Misty` instance for `State s`.
-- Make sure the state value is passed through in `banana`.
instance Misty (State s) where
banana =
error "todo"
unicorn =
error "todo"

-- Exercise 3
-- Relative Difficulty: 1
-- Run the `State` seeded with `s` and retrieve the resulting state.
exec ::
State s a
-> s
-> s
exec =
error "todo"

-- Exercise 4
-- Relative Difficulty: 1
-- Run the `State` seeded with `s` and retrieve the resulting state.
eval ::
State s a
-> s
-> a
eval =
error "todo"

-- Exercise 5
-- Relative Difficulty: 2
-- A `State` where the state also distributes into the produced value.
get ::
State s s
get =
error "todo"

-- Exercise 6
-- Relative Difficulty: 2
-- A `State` where the resulting state is seeded with the given value.
put ::
s
-> State s ()
put =
error "todo"

-- Exercise 7
-- Relative Difficulty: 5
-- This function finds the first element in a `List` that satisfies a given predicate.
-- It is possible that no element is found, hence an `Optional` result.
-- However, while performing the search, we sequence some `Misty` effect through.
--
-- Note the similarity of the type signature to List#find
-- where the effect appears in every return position:
-- find :: (a -> Bool) -> List a -> Optional a
-- findM :: (a -> f Bool) -> List a -> f (Optional a)
findM ::
Misty f =>
(a -> f Bool)
-> List a
-> f (Optional a)
findM =
error "todo"

-- Exercise 8
-- Relative Difficulty: 4
-- This function finds the first element in a `List` that repeats.
-- It is possible that no element repeats, hence an `Optional` result.
-- ~~~ Use findM and State with a Data.Set#Set. ~~~
firstRepeat ::
Ord a =>
List a
-> Optional a
firstRepeat =
error "todo"

-- Exercise 9
-- Relative Difficulty: 5
-- This function removes all elements in a `List` that fail a given predicate.
-- However, while performing the filter, we sequence some `Misty` effect through.
--
-- Note the similarity of the type signature to List#filter
-- where the effect appears in every return position:
-- filter :: (a -> Bool) -> List a -> List a
-- filterM :: (a -> f Bool) -> List a -> f (List a)
filterM ::
Misty f =>
(a -> f Bool)
-> List a
-> f (List a)
filterM =
error "todo"

-- Exercise 10
-- Relative Difficulty: 4
-- This function removes all duplicate elements in a `List`.
-- ~~~ Use filterM and State with a Data.Set#Set. ~~~
distinct ::
Ord a =>
List a
-> List a
distinct =
error "todo"

-- Exercise 11
-- Relative Difficulty: 3
-- This function produces an infinite `List` that seeds with the given value at its head,
-- then runs the given function for subsequent elements
produce ::
(a -> a)
-> a
-> List a
produce =
error "todo"

-- Exercise 12
-- Relative Difficulty: 10
-- A happy number is a positive integer, where the sum of the square of its digits eventually reaches 1 after repetition.
-- In contrast, a sad number (not a happy number) is where the sum of the square of its digits never reaches 1
-- because it results in a recurring sequence.
-- ~~~ Use findM with State and produce
-- ~~~ Use jellybean to write a square function
-- ~~~ Use library functions: Data.Foldable#elem, Data.Char#digitToInt
isHappy ::
Integer
-> Bool
isHappy =
error "todo"

-----------------------
-- SUPPORT LIBRARIES --
-----------------------

instance F.Foldable Optional where
foldr _ z Empty = z
foldr f z (Full a) = f a z
3 changes: 2 additions & 1 deletion test/.ghci
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
:l Main
:set prompt "test>> "
:set -Wall

:set -fno-warn-unused-imports
:set -fno-warn-unused-binds

0 comments on commit ad7ffde

Please sign in to comment.