Así que estoy jugando con esto:Conseguir un valor de tipo de una Integral => [a] a partir de un valor de una integral => ([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)
Y si bien tengo abundants_perfects_deficients
, prefiero tener tres valores: abundants
, perfects
, y deficients
todos de tipo Integral a -> [a]
.
Una cosa que no funciona es:
abundants,perfects,deficients :: Integral a => [a]
(abundants,perfects,deficients) = abundants_perfects_deficients
Debido a que este constriñe los tres para ser todos en el mismo a
.
que hemos probado algo que ver ellos uno por uno, para que no se limitará mutuamente, pero eso no funcionó bien:
perfects :: Integral a => [a]
(_,perfects,_) = abundants_perfects_deficients
Debido a que el compilador no pudo encontrar la manera de convertir un valor de tipo forall a. Integral a => ([a],[a],[a])
para escribir (t1, forall a. Integral a => [a], t2)
.
Lo que parece bastante chulo.
Ahora sé que podría implementar por separado (solo perfects = filter isPerfect [1..]
), o limitan a ser todos del mismo tipo ((abundants,perfects,deficients) = abundants_perfects_deficients
funciona bien si abundants,perfects,deficients :: [Integer]
), pero
- me gusta usar la información compartida para construir los tres
- Quiero simplemente no estando limitado a
Integer
s
ideas?
Editar: lo suficientemente fascinante esto funciona:
abundants :: Integral a => [a]
abundants = f as
where as :: [Integer]
(as,_,_) = abundants_perfects_deficients
f :: Integral a => [Integer] -> [a]
f = map fromInteger
pero esto no significa:
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'
no tengo ni idea de por qué.
no funcionará: 'FST :: (a, b) -> a' (y similar para snd) tendrá que proporcionar algunos nuevos accesores de tres tuplas;) –
Ops, tiene razón. Actualizado para arreglarlo. – nulvinge
necesita eliminar sus (.) Operadores (abundants_perfects_deficients no es una función) – rampion