git.iko.soy/production-haskell
on master help sign in
seminar 1
commitdd8560938a15da072a1e1c17b1a80cb9d22e1920 authoriko <mail@iko.soy> dateWed 14 Feb 2024, 21:06 (3 years ago) parent64ab3e7
4 files changed+68−17
seminars/1/package.yaml+1 seminars/1/shell.nix+11 seminars/1/src/Task.hs+53−15 seminars/1/task.cabal+3−2
seminars/1/package.yaml+1
@@ -4,6 +4,7 @@ license: Unlicense
44
55dependencies:
66 - base >= 4.7 && < 5
7+ - containers
78
89library:
910 source-dirs: src
seminars/1/shell.nixnew file+11
@@ -0,0 +1,11 @@
1+{ pkgs ? import <nixpkgs> { } }:
2+
3+let compilerVersion = "963";
4+in pkgs.mkShell {
5+ buildInputs = with pkgs; [
6+ haskell.compiler."ghc${compilerVersion}"
7+ (pkgs.haskell-language-server.override {
8+ supportedGhcVersions = [ compilerVersion ];
9+ })
10+ ];
11+}
seminars/1/src/Task.hs+53−15
@@ -1,3 +1,4 @@
1+{-# LANGUAGE InstanceSigs #-}
12module Task
23 ( -- * List Monoids
34 constructFirstMonoid,
@@ -27,7 +28,12 @@ module Task
2728 saveTheDiabetic,
2829 calculateSugarDanger,
2930 )
30−where
31+where
32+
33+import Data.Map (Map, empty, toList, insert, update, delete)
34+import Data.Monoid (Sum(..))
35+import qualified Data.Map
36+import Data.List (sortBy)
3137
3238-- _ _ _ __ __ _ _
3339-- | | (_)___| |_ | \/ | ___ _ __ ___ (_) __| |___
@@ -50,19 +56,24 @@ where
5056--
5157-- >>> (destructFirstMonoid . fold . fmap constructFirstMonoid) []
5258-- Nothing
53−data FirstMonoid a
5459
55−instance Semigroup (FirstMonoid a)
60+data FirstMonoid a = FM (Maybe a)
61+
62+instance Semigroup (FirstMonoid a) where
63+ (FM Nothing) <> x = x
64+ x <> _ = x
65+
5666
57−instance Monoid (FirstMonoid a)
67+instance Monoid (FirstMonoid a) where
68+ mempty = FM Nothing
5869
5970-- Warps an `a` in a `FirstMonoid`.
6071constructFirstMonoid :: a -> FirstMonoid a
61−constructFirstMonoid = error "TODO: constructFirstMonoid"
72+constructFirstMonoid = FM . Just
6273
6374-- Unwraps the `a` from a `FirstMonoid`, if there is one.
6475destructFirstMonoid :: FirstMonoid a -> Maybe a
65−destructFirstMonoid = error "TODO: destructFirstMonoid"
76+destructFirstMonoid (FM x) = x
6677
6778-- Write a datatype and a Monoid instance for it such that:
6879--
@@ -79,19 +90,22 @@ destructFirstMonoid = error "TODO: destructFirstMonoid"
7990--
8091-- >>> (destructLastMonoid . fold . fmap constructLastMonoid) []
8192-- Nothing
82−data LastMonoid a
93+data LastMonoid a = LM (Maybe a)
8394
84−instance Semigroup (LastMonoid a)
95+instance Semigroup (LastMonoid a) where
96+ x <> (LM Nothing) = x
97+ _ <> x = x
8598
86−instance Monoid (LastMonoid a)
99+instance Monoid (LastMonoid a) where
100+ mempty = LM Nothing
87101
88102-- Warps an `a` in a `LastMonoid`.
89103constructLastMonoid :: a -> LastMonoid a
90−constructLastMonoid = error "TODO: constructLastMonoid"
104+constructLastMonoid = LM . Just
91105
92106-- Unwraps the `a` from a `LastMonoid`, if there is one.
93107destructLastMonoid :: LastMonoid a -> Maybe a
94−destructLastMonoid = error "TODO: destructLastMonoid"
108+destructLastMonoid (LM x) = x
95109
96110-- _____ _ _ _ _
97111-- |_ _|__ __| | ___ | | (_)___| |_
@@ -105,7 +119,7 @@ destructLastMonoid = error "TODO: destructLastMonoid"
105119
106120-- | The priority of a task.
107121data Priority = Low | Medium | High
108− deriving (Show, Eq)
122+ deriving (Show, Eq, Ord)
109123
110124-- | The completion status of a task.
111125data Completion = Completed | NotCompleted
@@ -156,12 +170,35 @@ class TaskManager t where
156170 renameTask :: String -> String -> t -> t
157171
158172-- The task manager you are creating.
159−data MyTaskManager
173+data MyTaskManager = MTM (Map String (Completion, Priority))
160174
161175-- TODO: You have to make your 'MyTaskManager' an instance of
162176-- the 'TaskManager' typeclass.
163−instance TaskManager MyTaskManager
177+instance TaskManager MyTaskManager where
178+ emptyTaskManager = MTM empty
179+
180+ getPriorityList (MTM mp) = sortBy(\(_, lhs, _) (_, rhs, _) -> compare rhs lhs) $ (\(name, (comp, pri)) -> (comp, pri, name)) <$> toList mp
181+
182+ createTask :: String -> Priority -> MyTaskManager -> MyTaskManager
183+ createTask name pri (MTM mp) = MTM $ insert name (NotCompleted, pri) mp
184+
185+ toggleTaskCompletion name (MTM mp) = let
186+ toggleTask (Completed, pri) = (NotCompleted, pri)
187+ toggleTask (NotCompleted, pri) = (Completed, pri)
188+ in
189+ MTM $ update (Just . toggleTask) name mp
190+
191+ removeTask name (MTM mp) = MTM $ delete name mp
192+
193+ modifyPriority name newPri (MTM mp) = MTM $ update (\(comp, _) -> Just (comp, newPri)) name mp
164194
195+ renameTask oldName newName (MTM mp) = let
196+ mval = Data.Map.lookup oldName mp
197+ mp1 = delete oldName mp
198+ in
199+ case mval of
200+ Nothing -> MTM mp
201+ Just val -> MTM $ insert newName val mp1
165202-- ____ __ __
166203-- / ___|___ / _|/ _| ___ ___
167204-- | | / _ \| |_| |_ / _ \/ _ \
@@ -224,7 +261,8 @@ instance HasPrice CoffeeExtra where
224261 price BrownSugar = 35
225262
226263-- TODO: You want to make 'Coffee' an instance of 'HasPrice'.
227−instance HasPrice Coffee
264+instance HasPrice Coffee where
265+ price x = (cost x) + getSum (foldMap (Sum . price) (extras x))
228266
229267-- | A debit card.
230268-- Note: the balance can be negative.
seminars/1/task.cabal+3−2
@@ -4,12 +4,11 @@ cabal-version: 2.2
44--
55-- see: https://github.com/sol/hpack
66--
7−-- hash: e7ce4d16c67bf724ae661c06d421b31bdf4a8955874528858483b7ed2f59e002
7+-- hash: 781190f5d43564d9d73aa8b8a85a99c3d859a931a6ca644dadf871a105221b10
88
99name: task
1010version: 0.1.0.0
1111license: Unlicense
12−license-file: LICENSE
1312build-type: Simple
1413
1514library
@@ -23,6 +22,7 @@ library
2322 src
2423 build-depends:
2524 base >=4.7 && <5
25+ , containers
2626 default-language: Haskell2010
2727
2828test-suite task-tests
@@ -37,6 +37,7 @@ test-suite task-tests
3737 test
3838 build-depends:
3939 base >=4.7 && <5
40+ , containers
4041 , task
4142 , tasty
4243 , tasty-hunit