Difference between revisions of "99 questions/Solutions/14"

From HaskellWiki
Jump to navigation Jump to search
 
m
 
(9 intermediate revisions by 6 users not shown)
Line 17: Line 17:
 
</haskell>
 
</haskell>
   
  +
or, using the list instance of <hask>Applicative</hask>:
or, using concatMap:
 
  +
<haskell>
  +
dupli = (<**> [id,id])
  +
</haskell>
  +
 
or, using <hask>concatMap</hask>:
 
<haskell>
 
<haskell>
 
dupli = concatMap (\x -> [x,x])
 
dupli = concatMap (\x -> [x,x])
 
</haskell>
 
</haskell>
   
also using concatMap:
+
also using <hask>concatMap</hask>:
 
<haskell>
 
<haskell>
 
dupli = concatMap (replicate 2)
 
dupli = concatMap (replicate 2)
  +
</haskell>
  +
  +
or, using <hask>foldl</hask>:
  +
<haskell>
  +
dupli = foldl (\acc x -> acc ++ [x,x]) []
 
</haskell>
 
</haskell>
 
 
or, using foldr:
+
or, using <hask>foldr</hask>:
 
<haskell>
 
<haskell>
 
dupli = foldr (\ x xs -> x : x : xs) []
 
dupli = foldr (\ x xs -> x : x : xs) []
 
</haskell>
 
</haskell>
  +
  +
or, using silliness:
  +
<haskell>
  +
dupli = foldr (\x -> (x:) . (x:)) []
  +
</haskell>
  +
  +
or, even sillier:
  +
<haskell>
  +
dupli = foldr ((.) <$> (:) <*> (:)) []
  +
</haskell>
  +
  +
and here is the proof that <hask>((.) <$> (:) <*> (:)) = (\y z -> y:y:z)</hask>:
  +
  +
<haskell>
  +
(.) <$> (:) <*> (:) =
  +
((.) <$> (:)) <*> (:) = -- (<$>) is infixl 4, (<*>) is infixl 4
  +
((.) . (:)) <*> (:) = -- (<$>) == (.) for functions
  +
(\x -> (.) (x:)) <*> (:) = -- definition of (.)
  +
\y -> (\x -> (.) (x:)) y (y:) = -- definition of (<*>) for functions
  +
\y -> ((.) (y:)) (y:) = -- beta reduction (applying y to (\x -> (.) (x:)))
  +
\y -> (y:) . (y:) = -- changing (.) to its prefix form
  +
\y -> (\z -> (y:) ((y:) z)) = -- definition of (.)
  +
\y z -> y:y:z -- making it look nicer
  +
</haskell>
  +
  +
  +
[[Category:Programming exercise spoilers]]

Latest revision as of 20:45, 28 December 2014

(*) Duplicate the elements of a list.

dupli [] = []
dupli (x:xs) = x:x:dupli xs

or, using list comprehension syntax:

dupli list = concat [[x,x] | x <- list]

or, using the list monad:

dupli xs = xs >>= (\x -> [x,x])

or, using the list instance of Applicative:

dupli = (<**> [id,id])

or, using concatMap:

dupli = concatMap (\x -> [x,x])

also using concatMap:

dupli = concatMap (replicate 2)

or, using foldl:

dupli = foldl (\acc x -> acc ++ [x,x]) []

or, using foldr:

dupli = foldr (\ x xs -> x : x : xs) []

or, using silliness:

dupli = foldr (\x -> (x:) . (x:)) []

or, even sillier:

dupli = foldr ((.) <$> (:) <*> (:)) []

and here is the proof that ((.) <$> (:) <*> (:)) = (\y z -> y:y:z):

(.) <$> (:) <*> (:) =
((.) <$> (:)) <*> (:) = -- (<$>) is infixl 4, (<*>) is infixl 4
((.) . (:)) <*> (:) = -- (<$>) == (.) for functions
(\x -> (.) (x:)) <*> (:) = -- definition of (.)
\y -> (\x -> (.) (x:)) y (y:) = -- definition of (<*>) for functions
\y -> ((.) (y:)) (y:) = -- beta reduction (applying y to (\x -> (.) (x:)))
\y -> (y:) . (y:) = -- changing (.) to its prefix form
\y -> (\z -> (y:) ((y:) z)) = -- definition of (.)
\y z -> y:y:z -- making it look nicer