Send Beginners mailing list submissions to
        beginners@haskell.org

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
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

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 <peter.h...@memorphic.com>
Subject: [Haskell-beginners] Extracting arguments point-free
To: beginners@haskell.org
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 <peter.h...@memorphic.com>
Subject: Re: [Haskell-beginners] Extracting arguments point-free
To: beginners@haskell.org
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 <peter.h...@memorphic.com> 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
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 45, Issue 31
*****************************************

Reply via email to