Help me do this idiomatically (1/3)
data Context = Context Int
tagItems :: ([a], Context) -> ([(a, Int)], Context)
tagItems (ys, ctx) = foldl f ([], ctx) ys
where f (items, (Context x)) y = (items ++ [(y, x)], Context (x + 1))
main :: IO ()
main = do
let ctx = Context 1000
(items, ctx') = tagItems (["one", "two", "three"], ctx)
putStrLn $ show items
-- Yields: [("one",1000),("two",1001),("three",1002)]
Help me do this idiomatically (2/3)
import Data.List
import Data.Tuple
data Context = Context Int
tagItems :: ([a], Context) -> ([(a, Int)], Context)
tagItems (ys, ctx) = swap $ mapAccumL f ctx ys
where f (Context x) y = (Context (x + 1), (y, x))
main :: IO ()
main = do
let ctx = Context 1000
(items, ctx') = tagItems (["one", "two", "three"], ctx)
putStrLn $ show items
-- Yields: [("one",1000),("two",1001),("three",1002)]
Help me do this idiomatically (3/3)
- Should I use foldl' or foldr instead?
- If so, is it straightforward to maintain the ordering?
- Is there a more idiomatic way to do this kind of thing?
- How do I refactor this to use the state monad?
- Should I refactor this to use the state monad?
x : xs efficiency problem mentioned in Real World Haskell
asPattern :: [a] -> [a]
asPattern xs@(x : xs') = xs
noAsPattern :: [a] -> [a]
noAsPattern (x : xs) = (x : xs)
- Claim is that asPattern is more efficient than noAsPattern
- There are many comments about this in annotated online version of book
- Given how sophisticated GHC is reputed to be, it would worry me if the fairly obvious optimization isn't automatic
- What's the consensus?
Search and replace with ByteString
Language extension of interest: view patterns
{-# LANGUAGE ViewPatterns #-}
-- Abstract type: data constructor would typically not be exported
data Widget = Widget String String
createWidget n d = Widget n d
widgetName (Widget n _) = n
widgetDesc (Widget _ d) = d
-- View type and function dependent only on public interface
data WidgetV = WidgetV String String
widgetV w = WidgetV n d where n = widgetName w; d = widgetDesc w
-- Function that pattern-matches on view
demo (widgetV -> WidgetV n d) = "name = " ++ n ++ " desc = " ++ d
main = putStrLn $ demo $ createWidget "name" "desc"