2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 [Haskell] Помогите обобщить/факторизовать
Сообщение25.04.2017, 12:52 
…обобщить или факторизовать на что-то стандартное. Написался вот такой тип и вот такой пример работы с ним:

Используется синтаксис Haskell
data IOList a = IolNil | IolCons a (IO (IOList a))

numbers4 :: Int -> IOList Int
numbers4 n = IolCons n (return $ numbers4 (n + 1))

-- ещё и код не ахти какой, надо было переписать с do и вообще по-другому
takeIol :: Int -> IOList a -> IO [a]
takeIol n | n <= 0    = \_ -> return []
          | otherwise = f where
    f IolNil = return []
    f (IolCons x mxs) = mxs >>= \xs' -> (takeIol (n-1) xs' >>= \xs -> return $ x:xs)

ghci> takeIol 10 (numbers4 0)
[0,1,2,3,4,5,6,7,8,9]
 

и у меня складывается ощущение чего-то знакомого. [Сделать numbers4 :: Int -> IO [Int] не получается по понятным соображениям: придётся сначала связать результат вычисления хвоста, чтобы получить действие-результат, и так мы будем бесконечно вычислять хвосты.]

___

Мне тут пока видится вот что. Получить тип списков мы можем как фиксированную точку функтора

data ListLevel a next = Nil | Cons a next deriving Functor
type List a = Fix (ListLevel a)


Описанный тип можно получить аналогично, но обработав тип перед этим конструктором типа монады:

data IOList a = Fix (IO (ListLevel a))

— конечно, на самом деле мы так получим IO (IOList a) в смысле старого IOList, но оно, наверно, и более правильно.

Остаётся думать, что takeIol можно будет написать, используя свёртку, идущую в комплекте с Fix. Так ли это?

 
 
 [ 1 сообщение ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group