Получение значения типа Integral a => [a] из значения Integral a => ([a], [a], [a])

Итак, я играю с этим:

factors :: Integral a => a -> [a] 
factors n = filter (\d -> n `rem` d == 0) . takeWhile (\d -> d*d <= n) $ [ 1 .. ]

abundants_perfects_deficients :: Integral a => ([a],[a],[a])
abundants_perfects_deficients = foldr switch ([],[],[]) [1..]
  where switch :: Integral a => a -> ([a],[a],[a]) -> ([a],[a],[a])
        switch n (as,ps,ds) = 
          let t = sum (factors n) in
                if t < n  then  (as,ps,n:ds) 
          else  if t == n then  (as,n:ps,ds) 
          else                  (n:as,ps,ds)

И пока у меня есть sizes_perfects_deficients , я бы предпочел иметь три значения: изобилие , совершенство и дефицит все типа Интеграл a -> [a] .

Одна вещь, которая не работает, это:

abundants,perfects,deficients :: Integral a => [a] 
(abundants,perfects,deficients) = abundants_perfects_deficients

Потому что это заставляет всех трех быть одним и тем же a .

Я пытался что-то сделать с ними по очереди, чтобы они не ограничивали друг друга, но это тоже не сработало:

perfects :: Integral a => [a] 
(_,perfects,_) = abundants_perfects_deficients

Потому что компилятор не мог понять, как преобразовать значение типа для всех а. Интеграл a => ([a], [a], [a]) для типа (t1, forall a. Integral a => [a], t2) .

Что кажется достаточно приятным.

Теперь я знаю, что могу реализовать их по отдельности (просто perfects = filter isPerfect [1 ..] ) или ограничить их, чтобы все они были одного типа ( (изобилие, совершенство, недостатки ) = sizes_perfects_deficients отлично работает, если изобилие, совершенства, дефициты :: [Integer] ), но

  • мне нравится использовать общую информацию для построения всех трех
  • Я хочу не просто быть ограничено Integer s

идеями?


Править : Интересно, что это работает:

abundants :: Integral a => [a]
abundants = f as
  where as :: [Integer]
        (as,_,_) = abundants_perfects_deficients
        f :: Integral a => [Integer] -> [a]
        f = map fromInteger

Но это не так:

abundants_perfects_deficients' :: (Integral a,Integral p, Integral d) => ([a],[p],[d])
abundants_perfects_deficients' = (f as, f ps, f ds)
  where as,ps,ds :: [Integer]
        (as,ps,ds) = abundants_perfects_deficients
        f :: Integral a => [Integer] -> [a]
        f = map fromInteger

abundants,perfects,deficients :: (Integral a) => [a]
(abundants,perfects,deficients) = abundants_perfects_deficients'

Я понятия не имею, почему.

6
задан Pops 4 May 2012 в 15:48
поделиться