РЕДАКТИРОВАТЬ: я разместил это слишком быстро и не соответствует поведению, теперь должно быть хорошо.
import Control.Monad.Random
import Control.Monad (liftM, replicateM)
ЗНАНИЕ: Если вам нравятся случайные люди, тогда используйте MonadRandom - он качается.
STYLE: только импорт используемых вами символов улучшает удобочитаемость, а иногда и удобство обслуживания.
output :: IO [Double]
output = liftM (map dist) getLists
Примечание: я дал выводу явный тип, но знаю, что не имеет для ввода-вывода.
ТИП:
1) Обычно хорошо отделять ваш IO от чистых функций. Здесь я разделил получение случайных списков из расчета распределений. В вашем случае это было чисто, но вы комбинировали получение «случайных» списков через генератор с функцией распределения; Я бы разделил эти части.
2) Читать Обозначения, считающиеся вредными . Попробуйте использовать >>=
вместо
output = do
gen <- new
return $ dist gen
вы можете сделать:
output = new >>= dist
Вау!
dist :: [Int] -> Double
dist lst = (fromIntegral (sum lst) / fromIntegral (length lst))
getLists :: MonadRandom m => Int -> Int -> m [[Int]]
getLists m n= replicateM m (getList n)
ЗНАНИЕ В Control.Monad все, что заканчивается M
, похоже на оригинал, но для монад. В этом случае replicateM
должно быть знакомо, если вы использовали функцию Data.List replicate
.
getList :: MonadRandom m => Int -> m [Int]
getList m = liftM (map (subtract 1 . (*2)) . take m) (getRandomRs (0,1::Int))
STYLE: Если я делаю что-то много раз, мне нравится иметь один экземпляр в его собственной функции (getList), тогда повторение в отдельной функции.