LINUX.ORG.RU

вопрос по haskell

 


0

3

День добрый!

Недавно на досуге занялся изучением haskell и столкнулся с кучей непонятного. Например есть код

import Control.Monad

import System.IO

getValues = do hFlush stdout

     input <- getLine

     let tmp = read input

     if tmp == 0

     then return []

   else liftM (tmp :) (getValues)

main = do — чего то там она делает с полученным списком

почему getValues игнорирует первый элемент из списка,вводимого пользователем с клавиатуры? Ввод должен продолжаться до появления числа 0

★★★★

Ты что-то путаешь. Покажи функцию которая использует список.

KblCb ★★★★★
()

Запустил твой код:

import Control.Monad
import System.IO

getValues = do 
	hFlush stdout
	input <- getLine
	let tmp = read input
	if tmp == 0
	then return []
	else liftM (tmp :) (getValues)

main = print =<< getValues

*Main> getValues 
1
2
3
0
[1,2,3]

Ничего не игнорирует. Все введенные числа возвращаются.

Код можно немного облагородить.

import Control.Monad
import System.IO
import Control.Applicative

getValues = do 
	hFlush stdout
	input <- getLine
	case read input of
		0 -> return []
		x -> (x:) <$> getValues

main = print =<< getValues

ман лоркод

zinfandel ★★
()
Последнее исправление: zinfandel (всего исправлений: 1)

почему getValues игнорирует первый элемент из списка,вводимого пользователем с клавиатуры? Ввод должен продолжаться до появления числа 0

УМВР:

Prelude> :l sample
[1 of 1] Compiling Main             ( sample.hs, interpreted )
Ok, modules loaded: Main.
*Main> getValues
1
2
3
4
5
0
[1,2,3,4,5]

Только я бы заменил

input <- getLine
let tmp = read input

на tmp <- readLn, а liftM на <$> из Data.Functor.

PS. Для кода используй тег [code][/code]

theNamelessOne ★★★★★
()
Ответ на: комментарий от zinfandel

Код можно немного облагородить

Ещё можно в духе http://hackage.haskell.org/package/monad-loops

import Control.Monad

untilM' :: (Monad m, MonadPlus f) => (a -> Bool) -> m a -> m (f a)
untilM' p m = go where
  go = do { x <- m; if not (p x) then return mzero else mplus (return x) `liftM` go }

untilM :: Monad m => (a -> Bool) -> m a -> m [a]
untilM = untilM'

и тогда

default (Int)

main :: IO ()
main = print =<< untilM (/= 0) readLn
quasimoto ★★★★
()
import Control.Monad.Loops
unfoldWhileM (/= 0)  readLn
adzeitor
()

народ всем спасибо. погляжу зпвтра все с утра - ездили приятелю машину смотрели, потому весь вечер не у компа))

saibogo ★★★★
() автор топика

Огромное спасибо, всем откликнувшимся за советы и подсказки. Проблема оказалась в невнимательности. В предыдущей версии функции, она считывала ровно n данных из стандартного ввода. Это самое n принималось из входного потока в теле функции main. Собственно эту строчку забыл убрать после переделки функции.

saibogo ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.