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 Integer
s and returns a corresponding nested list of Char
s 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'
精彩评论