доброго времени суток
имеют место быть два глупых вопроса. первый (составной):
properFraction (liftM read $ getLine) --возвращает (b, IO a)
почему именно так? т.е. почему только второй элемент кортежа
находится внутри монады IO?
более того:
snd $ properFraction (liftM read $ getLine) --отрабатывает
fst $ properFraction (liftM read $ getLine) --приводит к ошибке
однако при всём этом функция
printTuple :: (a, b) -> IO ()
printTuple (int, frac) = do
print int
print frac
будучи вызванной в таком вот контексте
do val <- properFraction (liftM read $ getLine)
printTuple val
отрабатывает опять же без проблем
вопрос в следующем: откуда появляется различие между типами
элементов кортежа, возвращаемого properFraction, и куда оно
внезапно исчезает? то есть не то чобы оно совсем исчезало -
тип b может быть каким-нибудь (IO c), однако print (IO c) в таком
случае не должен отрабатывать - (IO c) не является экземпляром
Show
к сожалению сейчас без доступа к ghc, текст сообщений об ошибках
приведу завтра
ну и второй вопрос - как средствами библиотеки стандартной поставки
ghc произвести сравнение двух чисел с плавающей запятой с заданной
точностью (например, до пятого знака после запятой)?
заранее спасибо
так, меня осенило и первый вопрос частично разрешился: тип properFraction :: a -> (b, a), а стало быть при a = IO a: IO a -> (b, IO a). остался вопрос - как засунуть в IO b (и нужно ли это делать)?
> как засунуть в IO b (и нужно ли это делать)?
Нужно ли - вопрос конкретной задачи, а ты её не сформулировал.
Написать функцию типа (b, IO a) -> IO (b, a) - как два байта переслать:
f (y, iox) =
do x <- iox
return (y, x)
Или проще: f (y, iox) = liftM ((,) y) iox
> ну и второй вопрос - как средствами библиотеки стандартной поставки
ghc произвести сравнение двух чисел с плавающей запятой с заданной
точностью (например, до пятого знака после запятой)?
Ну, есть подозрение, что как обычно. Типа abs (x - y) < 0.00001 или что-то в этом роде...
properFraction :: (Integral b, RealFrac a) => a -> (b, a)
Поэтому твоё properFraction (liftM read $ getLine) просто нихрена не заработает. Потому как нет такой вещи, которая была бы IO что-то там и одновременно класса RealFrac.
>Поэтому твоё properFraction (liftM read $ getLine) просто нихрена не заработает. Потому как нет такой вещи, которая была бы IO что-то там и одновременно класса RealFrac
это до меня в принципе тоже дошло, однако с ясностью всё равно проблемы. то есть - что сделать-то чтобы оно заработало?
P.S. за ответы вообще спасибо большое. туплю, со мной бывает :(
> это до меня в принципе тоже дошло, однако с ясностью всё равно
проблемы. то есть - что сделать-то чтобы оно заработало?
А чего ты собственно хочешь? Уж не такого ли:
foo = do (x :: Double) <- getLine >>= return . read
print $ properFraction x
?