[Haskell-beginners] Extracting arguments point-free

Peter Hall peter.hall at memorphic.com
Sat Mar 24 22:18:03 CET 2012


As an exercise I'm trying to rewrite a Project Euler solution below to
be as point-free as possible.  I'm stuck trying to extract the
[1..999] range so it can be passed as an argument to calc. Can someone
help me figure it out?

Thanks,
Peter


module Problem0036 (
    run
) where

import Num.Digits
import Control.Applicative

run :: IO Int
run = return $ calc

calc :: Int
calc = sum $ filter isBinaryPalindrome decimalPalindromes

isBinaryPalindrome :: Int -> Bool
isBinaryPalindrome = (==) <$> (fromDigitsB . reverse . digitsB) <*> id

decimalPalindromes :: [Int]
decimalPalindromes = fromDigitsD <$> oddsAndEvens (digitsD <$> [1..999])
        where oddsAndEvens  = (++) <$> (oddDigits <$>) <*> (evenDigits <$>)
              evenDigits    = (++) <$> id              <*> reverse
              oddDigits     = (++) <$> reverse . tail  <*> id




-- The other imported module:

module Num.Digits (
     digits
    ,digitsD
    ,digitsB
    ,fromDigits
    ,fromDigitsB
    ,fromDigitsD
) where

import Data.Char (digitToInt)
import Data.List (insert, foldl1')

{-# INLINABLE digitsD #-}
digitsD :: Integral a => a -> [a]
digitsD = digits 10

{-# INLINABLE fromDigitsD #-}
fromDigitsD :: Integral a => [a] -> a
fromDigitsD = fromDigits 10

{-# INLINABLE digitsB #-}
digitsB :: Integral a => a -> [a]
digitsB = digits 2

{-# INLINABLE fromDigitsB #-}
fromDigitsB :: Integral a => [a] -> a
fromDigitsB = fromDigits 2

{-# INLINABLE digits #-}
digits :: Integral a => a -> a -> [a]
digits b 0 = [0]
digits b n = reverse $ digits' n
    where digits' 0 = []
          digits' n = r : digits' q
            where (q,r) = quotRem n b

{-# INLINABLE fromDigits #-}
fromDigits :: Integral a => a -> [a] -> a
fromDigits b = foldl1' (\i j -> b * i + j)



More information about the Beginners mailing list