Pregunta

Estoy aprendiendo Haskell y pegado tratando de comprender el sistema de tipos.

Estoy intentando escribir una función que devuelve la longitud de la serie 'La mitad o Tres más uno' para una entrada. Aquí está mi intento de la función, utilizando un enfoque recursivo (la función es válida para entradas centrales solamente):

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)

Aquí está el error que consigo cuando intento cargar este archivo en 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)

Producción take (truncate (5/2)) [1,2,3], así que soy incapaz de comprender este mensaje de error. ¿Dónde voy mal?

¿Fue útil?

Solución

El operador / en Haskell se utiliza para la división de coma flotante. Si realmente quería usar división de coma flotante y truncate, tendrá que utilizar fromIntegral en num primero para convertirlo en un número de punto flotante. El error que se obtiene está diciendo que no se puede usar la división fraccional de un número entero (5/2 funciona porque el compilador infiere un tipo de coma flotante para ambos números). Sin embargo, se puede hacer lo que quiera con mucha más facilidad, utilizando la función div. Esto se utiliza normalmente infija, rodeando el nombre de la función con acentos graves (esto funciona para cualquier función Haskell):

| even num = hotpoHelper (num `div` 2) (count+1)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top