foldM
(e.g. here and here) don't address the State
monad.import Control.Monad.State.Lazy
import Control.Monad ( foldM )
data Student = Student { name :: String, sid :: Int } deriving ( Show )
data TestResult = TestResult { tested :: Student, grade :: Int } deriving ( Show )
data Classroom = Classroom { students :: [ Student ] } deriving ( Show )
test :: Student -> State Classroom TestResult
test s = do { c <- get; put c { students = s:(students c) }; return $ TestResult { tested = s, grade = 2 * (sid s) } }
tests :: [ Student ] -> State Classroom [ TestResult ]
tests = mapM test
worst :: State Classroom TestResult
worst = return $ TestResult { tested = Student { name = "MMM", sid = 0 }, grade = 0 }
better :: TestResult -> TestResult -> State Classroom TestResult
better r1 r2 = return $ case (grade r1) < (grade r2) of { True -> r2; False -> r1 }
brightest :: [ Student ] -> State Classroom TestResult
brightest students = foldM better worst (tests students)
main = print $ evalState (brightest [ Student "X" 19, Student "Y" 49, Student "Z" 46 ]) (Classroom [])
Here are the errors I get - what am I missing ?
Main.hs:22:35: error: [GHC-83865]
• Couldn't match type ‘StateT
Classroom Data.Functor.Identity.Identity TestResult’
with ‘TestResult’
Expected: TestResult
Actual: State Classroom TestResult
• In the second argument of ‘foldM’, namely ‘worst’
In the expression: foldM better worst (tests students)
In an equation for ‘brightest’:
brightest students = foldM better worst (tests students)
|
22 | brightest students = foldM better worst (tests students)
| ^^^^^
Main.hs:22:42: error: [GHC-83865]
• Couldn't match type ‘[TestResult]’ with ‘TestResult’
Expected: StateT
Classroom Data.Functor.Identity.Identity TestResult
Actual: State Classroom [TestResult]
• In the third argument of ‘foldM’, namely ‘(tests students)’
In the expression: foldM better worst (tests students)
In an equation for ‘brightest’:
brightest students = foldM better worst (tests students)
|
22 | brightest students = foldM better worst (tests students)
| ^^^^^^^^^^^^^^
The foldM
function only expects the first argument to produce a monadic value. The second and third arguments should be normal values. So you need to do some unwrapping:
worst :: TestResult
worst = TestResult { tested = Student { name = "MMM", sid = 0 }, grade = 0 }
brightest :: [ Student ] -> State Classroom TestResult
brightest students = do
ts <- tests students
foldM better worst ts