[Haskell] funkcja random

0

Witam. Mam problem z programem w jezyku Haskell. Chce zeby program wczytywal liczbe, losowal inna liczbe a potem je porownywal. Tylko, ze nie wiem co jest zle w programie. Moze znajdzie sie ktos kto pomoze?

import Random

main = do 
        a <- drawInt 1 10
        putStr("Podaj liczbe: ")
        x <- getInt

        print a
        print x
	  
	  --if a == b then print a else putStr ("Podaj liczba" ++ b) --putStrLn ("Wieksza jest " ++ b)

getInt :: IO Int
getInt = readLn

drawInt :: Int -> Int -> IO Int
drawInt x y = getStdRandom (randomR (x,y))
0
import Random

main = do
        a <- drawInt 1 10
        putStrLn("Ja wylosowalem: " ++ (show a))
        putStrLn("Podaj liczbe: ")
        b <- getInt

        print a
        print b
         
        if a == b then putStrLn("Obie sa takie same") else 
            if a > b then putStrLn("Pierwsza jest wieksza: " ++ (show a)) else 
                putStrLn("Druga jest wieksza:  " ++ (show b))

getInt :: IO Int
getInt = readLn

drawInt :: Int -> Int -> IO Int
drawInt x y = getStdRandom (randomR (x,y))

przykładowe użycie:

Obie sa takie samergawron@foo:~$ ghc x.hs && ./a.out
Ja wylosowalem: 3
Podaj liczbe: 
12
3
12
Druga jest wieksza:  12
0

Po cholerę te nawiasy? Haskell to nie C++. Drabinka ifów? Bozia case of czy guardów nie dała? Ja wiem, że kod monadyczny jest bliski imperatywnego, ale bez przesady...

0

Pokaż lepszą wersję zamiast krytykować.

0

Dzieki wielkie RobertG za poprawke Bardzo mi pomogles. Teraz juz wiem czemu mi sie nie chcialo wczytac.

A mialabym jeszcze jedna prosbe. Co trzeba zrobic zeby stworzyc petle z warunkiem? Zeby powtarzalo sie tyle razy aż a i b beda rowne? Bo nie moge zabardzo znaleŹĆ takich rzeczy. Bo w innych (czyli nie jako main = do...) bylo odwolywanie sie przez rekurencje. A tu jak to by wygladalo?

0

Możesz wykorzystać rekurencję, np tak:

import Random

main = do
        a <- drawInt 1 10
        putStrLn("Ja wylosowalem: " ++ (show a))
        myLoop a

getInt :: IO Int
getInt = readLn

drawInt :: Int -> Int -> IO Int
drawInt x y = getStdRandom (randomR (x,y))

myLoop :: Int -> IO Bool
myLoop a = do
        putStrLn("Podaj liczbe: ")
        b <- getInt
        case compare a b of
            GT -> do putStrLn "a > b, dalej"
                     myLoop a
            LT -> do putStrLn "b < a, dalej"
                     myLoop a
            EQ -> do putStrLn "a == b, koniec"
                     return True 

Dla czytelności usunąłem drabinkę if'ów, tak jak sugerował Świętowit.

0

Dzieki wielkie! [browar] Z reszta zadania nie powinnam miec juz problemow. :d

Tylko mam jeszcze jedno pytanko. Co dokladnie znaczy GT, LT i EQ? Wiem, ze sa uzywane przy case w warunku ale moglbys cos wiecej o tym napisac?

0

Juz znalazlam to co to jest GT, EQ i LT. Dzieki za pomoc. ;]

0

Mam pytanie jak zrobić licznik, który będzie zliczał za którym razem zdołaliśmy odgadnąć liczbę wylosowaną i wypisać do pliku.

0

Normalnie, umiesz policzyć długość listy poprzez rekurencję ogonową, z użyciem akumulatora? Noo, to analogicznie:

zaKtorym n = zaKtorym' 1
    where
      zaKtorym'  c = loop =<< getNum
          where
            getNum = putStr "Podaj liczbe: " >> hFlush stdout >> readLn
            loop m | m == n    = return c
                   | otherwise = putStrLn "Zle!" >> zaKtorym' (c + 1)

Nieco specyficzny kod, mający tylko zobrazować ideę.

Oczywiście nic nie stoi na przeszkodzie coby np. zrobić listę odpowiedzi dopóki nie padnie właściwa i zwrócić jej długość. Na dobrą sprawę to można to na kilkanaście sposobów skonstruować, nawet typowo imperatywnie:

zaKtorym x = 
    do count <- newIORef 1

       let loop = do putStr "Podaj liczbe: " >> hFlush stdout
                     num <- readLn

                     unless (num == x)
                        (putStrLn "Zle!" >> (modifyIORef count (+ 1)) >> loop)
       loop

       readIORef count

Zapisać do pliku chyba umiesz, writeFile.

0

Potrzebowałem odpocząć od jednego projektu na chwilę, poza tym stwierdziłem, że tamto 'typowo imperatywne' było za mało imperatywne (jawna rekurencja itd. to zuooo):

zaKtorym x = 
    do let getNumber = 
               do putStr "Podaj liczbe: "
                  hFlush stdout 

                  readLn :: IO Int
                     
       let guess result = 
               do count <- liftIO $ newIORef 1

                  forever  $ do 
                    num <- liftIO $ getNumber

                    when (num == x) 
                         (result count)

                    liftIO $ putStrLn "Zle!"
                    liftIO $ modifyIORef count (+ 1)

       runContT (callCC guess) readIORef

ciekawe czy za coś takiego można wylecieć ze studiów?

1 użytkowników online, w tym zalogowanych: 0, gości: 1