简体   繁体   中英

Haskell iterate over a list

I know you suppose to think differently in Haskell, but can 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]]
iterateList = foldl1 (>>).concat.intersperse [putStrLn ""].(map.map) (\c ->  putStr $ if (c==0) then "X" else "Y")

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 Integer s and returns a corresponding nested list of Char s according to the valueOf rule

解决方案

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM