开发者

Haskell iterate over a list

I know you suppose to think differently in Haskell, but c开发者_如何学Pythonan someone give me a quick answer on how to iterate over a list or nested list and print out a character based on the value of the list element.

list1 = [[1 0 0][0 1 0][0 0 1]]

By iterate through this nested list, it should print out x for 0 and y for 1

yxx
xyx
xxy

Thanks


First of all, I think you mean:

list1 :: [[Int]]
list1 = [[1,0,0],[0,1,0],[0,0,1]]

As for what you want:

valueOf :: Int -> Char
valueOf 0 = 'x'
valueOf 1 = 'y'
valueOf _ = 'z'

listValues :: [[Int]] -> [String]
listValues = map (map valueOf)

printValues :: [[Int]] -> IO ()
printValues = putStrLn . unlines . listValues

And then in ghci:

*Main> printValues list1 
yxx
xyx
xxy


Try this:

fun :: [[Int]] -> [String]
fun = (map . map) (\x -> if x == 0 then 'x' else 'y')

If you really need printing of result:

printSomeFancyList :: [[Int]] -> IO ()
printSomeFancyList = putStrLn . unlines . fun


define f by something like

f x = if x == 0 then 'x' else 'y'

then

map (map f) [[1,0,0],[0,1,0],[0,0,1]]

is what you want or if you want it fancier:

map' = map.map
map' f [[1,0,0],[0,1,0],[0,0,1]]


The solutions using map are the preferred Haskell style. But while you're learning, you may find explicit recursion easier to follow. Like so:

charSub :: Int -> Char
charSub 0 = 'x'
charSub 1 = 'y'
charSub x = error "Non-binary value!"

listSub :: [Int] -> String
listSub [] = []
listSub (x:xs) = (charSub x) : (listSub xs)

nestedSub :: [[Int]] -> String
nestedSub [] = []
nestedSub (y:ys) = (listSub y) ++ "\n" ++ (nestedSub ys) 

map does pretty much the same thing--it applies a function to each element in a list. But it may be easier to see what's going on here.


If you are interested in arbitrary nested lists, then you can write something like this (an arbitrary nested list is essentially a tree):

data Nested a = Leaf a | Nest [Nested a] deriving Show

traverse :: Nested Integer -> Nested Char
traverse (Leaf x) = Leaf (valueOf x)
traverse (Nest xs) = Nest (map traverse xs)

valueOf :: Integer -> Char
valueOf 0 = 'x'
valueOf 1 = 'y'
valueOf _ = 'z'

With that you can do:

Main> let nl = Nest [Leaf 1, Leaf 0, Nest [Leaf 0, Leaf 0, Leaf 1, Nest [Leaf 1, Leaf 1, Leaf 0]], Nest [Leaf 1, Leaf 1]]
Main> traverse nl
Nest [Leaf 'y',Leaf 'x',Nest [Leaf 'x',Leaf 'x',Leaf 'y',Nest [Leaf 'y',Leaf 'y',Leaf 'x']],Nest [Leaf 'y',Leaf 'y']]

The function traverse takes an arbitrary nested list of Integers and returns a corresponding nested list of Chars according to the valueOf rule


iterateList = foldl1 (>>).concat.intersperse [putStrLn ""].(map.map) (\c ->  putStr $ if (c==0) then "X" else "Y")


The solutions

cambiar = putStr.unlines.(map (map f)) where f x = if x == 0 then 'x' else 'y'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜