Pergunta

Estou aprendendo Haskell e preso tentando entender o sistema de tipos.

Estou tentando escrever uma função que retorne o comprimento da série 'meio ou três mais um' para uma entrada. Aqui está minha tentativa de função, usando uma abordagem recursiva (a função é válida apenas para entradas integrais):

hotpo :: (Integral a) => a->a
hotpo n = hotpoHelper n 1

hotpoHelper:: (Integral a) => a->a->a
hotpoHelper 1 n = n
hotpoHelper num count
    | even num = hotpoHelper (truncate (num/2)) (count+1)
    | otherwise = hotpoHelper (3*num+1) (count+1)

Aqui está o erro que recebo quando tento carregar este arquivo no GHC 6.12.3

test.hs:8:30:
    Could not deduce (RealFrac a) from the context (Integral a)
      arising from a use of `truncate' at test.hs:8:30-45
    Possible fix:
      add (RealFrac a) to the context of
        the type signature for `hotpoHelper'
    In the first argument of `hotpoHelper', namely
        `(truncate (num / 2))'
    In the expression: hotpoHelper (truncate (num / 2)) (count + 1)
    In the definition of `hotpoHelper':
        hotpoHelper num count
                      | even num = hotpoHelper (truncate (num / 2)) (count + 1)
                      | otherwise = hotpoHelper (3 * num + 1) (count + 1)

take (truncate (5/2)) [1,2,3] Funciona, então não consigo entender esta mensagem de erro. Onde eu estou errando?

Foi útil?

Solução

o / O operador em Haskell é usado para divisão de pontos flutuantes. Se você realmente queria usar a divisão de pontos flutuantes e truncate, você usaria fromIntegral sobre num primeiro a convertê -lo em um número de ponto flutuante. O erro que você recebe é dizer que você não pode usar a divisão fracionária em um número integral (5/2 funciona porque o compilador infere um tipo de ponto flutuante para ambos os números). No entanto, você pode fazer o que quiser com muito mais facilidade, usando o div função. Isso é normalmente usado infix, ao redor do nome da função com backquotes (isso funciona para qualquer função Haskell):

| even num = hotpoHelper (num `div` 2) (count+1)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top