My attempt at Advent of Code 2018, completely in Haskell with automatic input fetching, running and submission. As a Haskell beginner, this serves as a platform for me to learn more about using some real world Haskell packages, as well as certain advanced Haskell concepts such as existentialisation.
This is very much inspired by mstksg/advent-of-code-2018!
Submit answers with the SubmitAnswer
executable:
stack run SubmitAnswer
Run all unit tests:
stack test
We can standardise the declaration of all challenge solutions in a single record type, where we can declare how to parse an input, solve the problem with the given input, and show the result. This separation of concerns allows us to test the sSolve
function without involving the parse and show methods.
data Challenge = forall a b. (Show b, Typeable b) =>
Challenge
{ day :: Int
, level :: Int
, sParse :: T.Text -> a
, sSolve :: a -> b
}
By making Challenge
existential, we can still create a homogenous [Challenge]
list by hiding the inner a
and b
types. If on the other hand we had parameterised the Challenge
ADT as such, our list is no longer homogenous.
data Challenge' a b = (Show b, Typeable b) => Challenge'
{ day :: Int
, level :: Int
, sParse :: T.Text -> a
, sSolve :: a -> b
}
challenges = [challengeA :: Challenge' String Int, challengeB :: Challenge' Int Int]
-- <interactive>:16:52: error:
-- • Couldn't match type ‘Int’ with ‘[Char]’
-- Expected type: Challenge' String Int
-- Actual type: Challenge' Int Int