Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Extracting arguments point-free (Peter Hall)
2. Re: Extracting arguments point-free (Peter Hall)
----------------------------------------------------------------------
Message: 1
Date: Sat, 24 Mar 2012 21:18:03 +0000
From: Peter Hall <[email protected]>
Subject: [Haskell-beginners] Extracting arguments point-free
To: [email protected]
Message-ID:
<CAA6hAk5zYfOCWdz5=zftgw5pjb_ovls1bf74-tmnsiz4qgn...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
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)
------------------------------
Message: 2
Date: Sun, 25 Mar 2012 00:45:38 +0000
From: Peter Hall <[email protected]>
Subject: Re: [Haskell-beginners] Extracting arguments point-free
To: [email protected]
Message-ID:
<CAA6hAk5+vivi1XX=eocpbbvn2ijmLgm=34hfow4tmhiwauo...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Ok, I got it. I was confusing myself with <$> and some of those are
clearer with map. I ended up with this, which I'm happy with:
run :: IO Int
run = return $ calc [1..999]
calc :: [Int] -> Int
calc = sum . filter isBinaryPalindrome . decimalPalindromes
isBinaryPalindrome :: Int -> Bool
isBinaryPalindrome = (==) <$> (fromDigitsB . reverse . digitsB) <*> id
decimalPalindromes :: [Int] -> [Int]
decimalPalindromes = map fromDigitsD . oddsAndEvens . map digitsD
where oddsAndEvens = (++) <$> (map oddDigits) <*> (map evenDigits)
evenDigits = (++) <$> id <*> reverse
oddDigits = (++) <$> reverse . tail <*> id
Peter
On 24 March 2012 21:18, Peter Hall <[email protected]> wrote:
> 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)
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 45, Issue 31
*****************************************