I/O how can i put somehing in screen withouth being string? - haskell
So im doing this function and i need her to display on the screen the result of (premio ap x) , the problem is that (premio ap x)::Maybe Int , so its not a string.
joga :: Aposta -> IO ()
joga x= do
ap <- leAposta;
let arroz = (premio ap x)
putStr ^^^^^^^^^^
return ()
How can i convert this to a string? Or there is another way to display on the screen things that are not strings.
update :full code
comuns :: Aposta -> Aposta -> (Int,Int)
comuns (Ap a (b,c)) (Ap k (l,ç)) = (cnum a k, cnum [b,c] [l,ç])
cnum::[Int]->[Int]->Int
cnum [] l2 = 0
cnum (x:xs) l2 | elem x l2 = 1 + cnum xs l2
|otherwise = cnum xs l2
premio :: Aposta -> Aposta -> Maybe Int
premio l1 l2 | x == (5,2)= Just 1
| x == (5,1)= Just 2
| x == (5,0)= Just 3
| x == (4,2)= Just 4
| x == (4,1)= Just 5
| x == (4,0)= Just 6
| x == (3,2)= Just 7
| x == (2,2)= Just 8
| x == (3,1)= Just 9
| x == (3,0)= Just 10
| x == (1,2)= Just 11
| x == (2,1)= Just 12
| x == (2,0)= Just 13
|otherwise = Nothing
where
x = comuns l1 l2
leAposta :: IO Aposta
leAposta = do
putStrLn "Insira como lista as 5 estrelas"
num <-getLine
putStrLn "Insira em par as 2 estrelas"
es<-getLine
let ap = (Ap (read num) (read es))
if (valida ap)
then return ap
else do
putStrLn "Aposta invalida"
leAposta
Since arroz is premio ap x which has type Maybe Int, you can simply print arroz.
print works on any type that can be printed, i.e. on those types in class Show.
(You probably don't want to use print on values that are already strings, though, since that will print the escaped string, with quotes around. Use putStr and putStrLn for strings.)
Related
Haskell make recursion for Chars in String
I want to create game Magic 15 Puzzle in Haskell I have function set :: [[Char]] -> Char -> [[Char]] . It switches Char with empty space in [[Char]]. *Main> pp puzzle2 AC DE FBHIJ KGLNO PQMRS UVWXT *Main> pp (set puzzle2 'C') A CDE FBHIJ KGLNO PQMRS UVWXT *Main> Now I want to do recursion for [Char] (or String) like this (To do set xs for previous set x) puzzle :: Result -> [Char] -> Result puzzle gameboard (x:xs) = set (set (x:xs) x) xs But compilation says it is error: Couldn't match expected type ‘Char’ with actual type ‘[Char]’ I expect this output: *Main> pp(puzzle puzzle2 "CB") ABCDE F HIJ KGLNO PQMRS UVWXT What can I do to solve this? Thanks a lot in advance for answer! Whole Code: import Data.Char type Result = [String] pp :: Result -> IO () pp x = putStr (concat (map (++"\n") x)) puzzle2 :: [[Char]] puzzle2 = ["AC DE", "FBHIJ", "KGLNO", "PQMRS", "UVWXT"] getCords board x = head ( head [[(row_index, column_index) |(column_index, char) <- zip[1..] row, x == char] |(row_index,row)<- zip [1..]board,x `elem` row]) getRow board c = fst ( getCords board c) getCol board c = snd ( getCords board c) check ch1 ch2 board = (getRow board ch2 == getRow board ch1 + 1 || getRow board ch2 == getRow board ch1 - 1) && (getCol board ch1 == getCol board ch2) || ((getRow board ch1 == getRow board ch2) && (getCol board ch2 == getCol board ch1 + 1 || getCol board ch2 == getCol board ch1 - 1) ) set gameboard x | check x ' ' gameboard = [[if ch == ' ' then x else if ch == x then ' ' else ch | ch<- line] | line<-gameboard] | not (check x ' ' gameboard ) = [[ch | ch<- line] | line<-gameboard] puzzle :: Result -> [Char] -> Result puzzle gameboard (x:xs) = set (set (x:xs) x) xs
Just change the last function to puzzle :: Result -> [Char] -> Result puzzle g [] = g puzzle g (x:xs) = puzzle (set g x) xs
Numbering some integer partitions
These trees represent the integer partitions of n <= 5 with at most m = 3 parts. 1 2 3 4 5 | / \ / \ | | / \ / \ | | / \ / \ | 1,1 2,1 2,2 3,1 3,2 4,1 | | | | | | | | | | | | 1,1,1 2,1,1 2,2,1 3,1,1 Let's enumerate them from top to bottom and left to right: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 I need a list D such that D!!i is, if P is the partition numbered by i, the number of the partition P ++ [1]. That is, for this example, D!!1 = 6, because (1,1) has number 6 D!!2 = 7 because (2,1) has number 7. D!!3 = 9 because (3,1) has number 9. D!!4 = 11 because (4,1) has number 11. D!!5 = "nothing" because there's no child (5,1). D!!6 = 12 because (1,1) has number 6 and (1,1,1) has number 12. And so on, D!!7 = 13, D!!8 = 14, and D!!9 = 15. I have absolutely no idea how to start. I know SO is not a code writing service but I'm asking only for any hints. EDIT Here is an attempt. dico' :: Int -> Int -> Seq (Maybe Int) dico' m n = go 1 S.empty where go :: Int -> Seq (Maybe Int) -> Seq (Maybe Int) go k d' | k == n-1 = d' | otherwise = go (k+1) (inner 0 [0] [m] [m] 0 d') where inner :: Int -> [Int] -> [Int] -> [Int] -> Int -> Seq (Maybe Int) -> Seq (Maybe Int) inner i a b c end d | i >= length a = d -- what is the terminating condition here ? | otherwise = if b!!i > 0 then let l = min (b!!i) (c!!i) in let dd = d |> (Just $ end+1) in inner (i+1) (a ++ [end + 1 .. end + l]) (b ++ map (\x -> b!!i - x) [1 .. l]) (c ++ [1 .. l]) (end + l) dd else inner (i+1) a b c end (d |> Nothing) It works except that the result is too long. I don't find the appropriate terminating condition of the inner loop. > dico' 5 3 fromList [Just 1,Just 6,Just 7,Just 9,Just 11,Nothing,Just 12,Just 13,Just 14,Just 15,Nothing,Nothing,Just 16,Just 17,Nothing,Nothing,Just 18,Nothing,Nothing] EDIT 2 Ok I get it now. I'm still interested in any improvement. a008284_tabl :: [[Int]] a008284_tabl = [1] : f [[1]] where f xss = ys : f (ys : xss) where ys = map sum (zipWith take [1..] xss) ++ [1] _P :: Int -> Int -> Int _P m n = sum (concatMap (take (min m n)) (take m a008284_tabl)) dico' :: Int -> Int -> Seq (Maybe Int) dico' m n = go 1 S.empty where pmn = Just $ Just $ _P m n go :: Int -> Seq (Maybe Int) -> Seq (Maybe Int) go k d' | k == n-1 = d' | otherwise = go (k+1) (inner 0 [0] [m] [m] 0 d') where inner :: Int -> [Int] -> [Int] -> [Int] -> Int -> Seq (Maybe Int) -> Seq (Maybe Int) inner i a b c end d | S.lookup (S.length d - 1) d == pmn = d | otherwise = let bi = b!!i in if bi > 0 then let l = min bi (c!!i) in let dd = d |> (Just $ end+1) in let range1l = [1 .. l] in inner (i+1) (a ++ [end + 1 .. end + l]) (b ++ map (\x -> bi - x) range1l) (c ++ range1l) (end + l) dd else inner (i+1) a b c end (d |> Nothing) > dico' 5 3 fromList [Just 1,Just 6,Just 7,Just 9,Just 11,Nothing,Just 12,Just 13,Just 14,Just 15] > dico' 10 7 fromList [Just 1,Just 11,Just 12,Just 14,Just 17,Just 21,Just 26,Just 30,Just 33,Just 35,Nothing,Just 36,Just 37,Just 38,Just 40,Just 41,Just 43,Just 46,Just 47,Just 49,Just 52,Just 54,Just 55,Just 57,Just 59,Nothing,Just 60,Just 61,Just 63,Nothing,Just 64,Just 65,Nothing,Just 66,Nothing,Nothing,Just 67,Just 68,Just 69,Just 70,Just 72,Just 73,Just 74,Just 76,Just 77,Just 79,Just 80,Just 81,Just 82,Just 84,Just 85,Nothing,Just 86,Nothing,Just 87,Just 88,Just 89,Just 90,Nothing,Nothing,Just 91,Just 92,Nothing,Nothing,Just 93,Nothing,Nothing,Just 94,Just 95,Just 96,Just 97,Just 98,Just 100,Just 101,Just 102,Just 103,Just 104,Just 105,Nothing,Nothing,Just 106,Just 107,Just 108,Nothing,Just 109,Nothing,Nothing,Just 110,Just 111,Nothing,Nothing,Just 112,Nothing,Nothing,Just 113,Just 114,Just 115,Just 116,Just 117,Nothing,Just 118,Just 119,Just 120,Nothing,Just 121,Nothing,Just 122,Just 123,Nothing,Nothing,Just 124,Nothing,Nothing,Just 125,Just 126,Just 127,Just 128,Nothing,Just 129,Just 130,Nothing,Nothing,Just 131]
Haskell program that gives pretty prime numbers
I've made a haskell program that computes pretty prime numbers. Pretty primes are primes that are very close to a power of 2. You give 2 numbers for example: 10 and 20 then it returns 17 because 17 is the closest to a power of 2. 17 - 16 = 1 so it is the closest. I've made this: EDIT: I've rewrote the primefunction like this and e verw function but still getting -1. -- Geeft priemgetallen terug tussen de 2 grenzen -- English: Gives primenumbers between 2 numbers priemgetallen :: Int->[Int] priemgetallen b = take b (zeef [2..]) where zeef (p:xs) = p : zeef [x | x<-xs, (mod x p) /= 0] -- Geeft machten terug tussen de 2 grenzen -- English: Gives powers of 2 between 2 numbers machten :: Int->Int->[Int] machten a b | a <= 2 = 2:[2^x| x<-[2..b], (2^x) `mod` 2 == 0, 2^x < b, 2^x > a] | otherwise = [2^x| x<-[2..b], (2^x) `mod` 2 == 0, 2^x < b, 2^x > a] -- English: the start of the function prettyprime :: Int->Int->Int prettyprime a b = vergelijk ( verw a (priemgetallen b)) (machten a b) -- Filter the list verw :: Int->[Int]->[Int] verw _ [] = [] verw k (x:xs) | x > k = [x] ++ verw k xs | otherwise = verw k xs -- Vergelijkt alle priemgetallen en geeft welke korste bij het ander ligt -- English this function must see what primenumber is the closest to a power of 2 but I can't fix it vergelijk :: [Int]->[Int]->Int vergelijk [] _ = -1 vergelijk _ [] = -1 vergelijk (x:xs) (y:ys) | x - y < vergelijk (x:xs) ys = x | x - y > vergelijk (x:xs) ys = vergelijk xs (y:ys) | x - y == vergelijk (x:xs) ys = x main = do print $ prettyprime 14 20 Can someone help me? Kind regards,
The incomplete pattern is because you've omitted the case when x - y == vergelijk (x:xs) ys. The compiler is capable of warning you about this if you add -fwarn-incomplete-patterns and convert your guards into a real case: vergelijk (x:xs) (y:ys) = case compare (x - y) (vergelijk (x:xs) ys) of LT -> x -- you will get a warning about having no case for EQ GT -> vergelijk xs (y:ys) As a bonus, this version is much less likely to recompute the recursive call, especially on low optimization levels.
FizzBuzz cleanup
I'm still learning Haskell, and I was wondering if there is a less verbose way to express the below statement using 1 line of code: map (\x -> (x, (if mod x 3 == 0 then "fizz" else "") ++ if mod x 5 == 0 then "buzz" else "")) [1..100] Produces: [(1,""),(2,""),(3,"fizz"),(4,""),(5,"buzz"),(6,"fizz"),(7,""),(8,""),(9,"fizz"),(10,"buzz"),(11,""),(12,"fizz"),(13,""),(14,""),(15,"fizzbuzz"),(16,""),(17,""),(18,"fizz"),(19,""),(20,"buzz"),(21,"fizz"),(22,""),(23,""),(24,"fizz"),(25,"buzz"),(26,""),(27,"fizz"),(28,""),(29,""),(30,"fizzbuzz"), etc It just feels like I'm fighting the syntax more than I should. I've seen other questions for this in Haskell, but I'm looking for the most optimal way to express this in a single statement (trying to understand how to work the syntax better).
We need no stinkin' mod... zip [1..100] $ zipWith (++) (cycle ["","","fizz"]) (cycle ["","","","","buzz"]) or slightly shorter import Data.Function(on) zip [1..100] $ (zipWith (++) `on` cycle) ["","","fizz"] ["","","","","buzz"] Or the brute force way: zip [1..100] $ cycle ["","","fizz","","buzz","fizz","","","fizz","buzz","","fizz","","","fizzbuzz"]
If you insist on a one-liner: [(x, concat $ ["fizz" | mod x 3 == 0] ++ ["buzz" | mod x 5 == 0]) | x <- [1..100]]
How's about... fizzBuzz = [(x, fizz x ++ buzz x) | x <- [1..100]] where fizz n | n `mod` 3 == 0 = "fizz" | otherwise = "" buzz n | n `mod` 5 == 0 = "buzz" | otherwise = ""
Couldn't resist going in the other direction and making it more complicated. Look, no mod... merge as#(a#(ia,sa):as') bs#(b#(ib,sb):bs') = case compare ia ib of LT -> a : merge as' bs GT -> b : merge as bs' EQ -> (ia, sa++sb) : merge as' bs' merge as bs = as ++ bs zz (n,s) = [(i, s) | i <- [n,2*n..]] fizzBuzz = foldr merge [] $ map zz [(1,""), (3,"fizz"), (5,"buzz")]
Along the same lines as larsmans' answer: fizzBuzz = [(x, f 3 "fizz" x ++ f 5 "buzz" x) | x <- [1..100]] where f k s n | n `mod` k == 0 = s | otherwise = ""
I think the reason why you feel like you are fighting the syntax is because you are mixing too many types. Instead of trying to print: [(1, ""), (2,""), (3,"Fizz")...] Just think of printing strings: ["1","2","Fizz"...] My attempt: Prelude> let fizzBuzz x | x `mod` 15 == 0 = "FizzBuzz" | x `mod` 5 == 0 = "Buzz" | x `mod` 3 == 0 = "Fizz" | otherwise = show x Prelude> [fizzBuzz x | x <-[1..100]] ["1","2","Fizz","4","Buzz","Fizz","7","8","Fizz","Buzz","11","Fizz","13","14","FizzBuzz"...] In order to convert an Int to String you use the: show x
Just for studying zipWith (\a b -> b a) (map show [1..100]) $ cycle [id,id,const "fizz",id,const "buzz",const "fizz",id,id,const "fizz",const "buzz",id,const "fizz",id,id,const "fizzbuzz"] produces ["1","2","fizz","4","buzz","fizz","7","8","fizz","buzz","11","fizz","13","14","fizzbuzz","16","17","fizz","19","buzz","fizz","22","23","fizz","buzz","26","fizz","28","29","fizzbuzz","31","32","fizz","34","buzz","fizz","37","38","fizz","buzz","41","fizz","43","44","fizzbuzz","46","47","fizz","49","buzz","fizz","52","53","fizz","buzz","56","fizz","58","59","fizzbuzz","61","62","fizz","64","buzz","fizz","67","68","fizz","buzz","71","fizz","73","74","fizzbuzz","76","77","fizz","79","buzz","fizz","82","83","fizz","buzz","86","fizz","88","89","fizzbuzz","91","92","fizz","94","buzz","fizz","97","98","fizz","buzz"]
Writer monad may look nice (if you don't like concat): fizzBuzz = [(x, execWriter $ when (x `mod` 3 == 0) (tell "fizz") >> when (x `mod` 5 == 0) (tell "buzz")) | x <- [1..100]] It's not particularly succinct though.
How to check that I'm dealing with a list in Haskell?
I'm learning Haskell, and I'm trying to add preconditions to a (trivial, as an exercise) element_at function (code below). I've created a "helper" elem_at_r because otherwise, len x fails at some point (when x is a 'literal' rather than a list? - I still have trouble parsing ghci's error messages). elem_at now has all the error checking, and elem_at_r does the work. In elem_at, I'd like to add a check that x is indeed a list (and not a 'literal'). How can I do that? len x = sum [ 1 | a <- x] elem_at_r x n | n == 0 = head x | 0 < n = elem_at_r (tail x) (n-1) elem_at x n | x == [] = error "Need non-empty list" | len x <= n = error "n too large " ++ show (len x) | n < 0 = error "Need positive n" | otherwise = elem_at_r x n Thanks! Frank
Due to Haskell's type system, elem_at can only take a list as its first argument (x); if you try to pass a non-list, GHC will detect this and give an error at compile time (or interpretation time in GHCi). I don't know why len would "fail"; could you post the error message that GHCi gives you?
It looks like you were getting errors because of the "x == []" line. The code below pattern matches for that condition and adds a few signatures. Otherwise it is the same. Hope it helps. len x = sum [ 1 | a <- x] elem_at_r :: [a] -> Int -> a elem_at_r x n | n == 0 = head x | 0 < n = elem_at_r (tail x) (n-1) elem_at :: [a] -> Int -> a elem_at [] _ = error "Need non-empty list" elem_at x n | len x <= n = error ("n too large " ++ show (len x)) | n < 0 = error "Need positive n" | otherwise = elem_at_r x n You could also make your helper functions part of this function using a where clause: elem_at :: [a] -> Int -> a elem_at [] _ = error "Need non-empty list" elem_at x n | len x <= n = error ("n too large " ++ show (len x)) | n < 0 = error "Need positive n" | otherwise = elem_at_r x n where len :: [a] -> Int len x = sum [ 1 | a <- x] elem_at_r :: [a] -> Int -> a elem_at_r x n | n == 0 = head x | 0 < n = elem_at_r (tail x) (n-1)