I am learning Haskell, and what is better than advent of code to do so? The day 1 problem is about adding together the digits that are followed by the same digit from a "circular" string (the next of the last is the first). My solution is the following:
import Data.List
import Data.Char
result :: [Char] -> Int
result s = sum . map (digitToInt . fst)
. filter (uncurry (==))
. zip s
$ (drop 1 . cycle $ s)
My question is not only about the algorithm (I think that it is ok, and the problem is not that difficult) but also about the "haskellish" style.
Because I am used to Rust/Ocaml/Elm etc., at first I wrote:
import Data.List
import Data.Char
import Data.Function
result :: [Char] -> Int
result str = str & zip (drop 1 . cycle $ str)
& filter (uncurry (==))
& map (digitToInt . fst)
& sum
then I read that Haskell people prefer to compose functions and then pass the parameter, not doing the forward thing. What do you think about that?
Also, I searched over the Internet, and I found some divided code, more like that:
import Data.List
import Data.Char
transformCharPairsToInts :: [(Char, Char)] -> [Int]
transformCharPairsToInts = map $ digitToInt . fst
keepPairsWithSameChars :: [(Char, Char)] -> [(Char, Char)]
keepPairsWithSameChars = filter $ uncurry (==)
result :: [Char] -> Int
result str = sum . transformCharPairsToInts . keepPairsWithSameChars $ zip str shiftedStr
where
shiftedStr = drop 1 . cycle $ str
What is the most idiomatic thing? The style that Haskell people prefer?
The main:
-- exemple cases
main = mapM_ (print . result) $ ["1122", "1111", "1234", "91212129"]
Thank you for your remarks.