Haskell type errors

I am really new to Haskell and this gives me ample time. I tried to write a basic function like "linspace" in Matlab, but the compiler seems to reject the idea that "gender" creates an Integral type. My code:

linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
    | y' == y   = [x + i * dx | i <- nums]
    | otherwise = ([x + i * dx | i <- nums] ++ [y])
    where
        n = floor ((y - x) / dx)
        nums = [0..n]
        y' = (x + (fromIntegral n) * dx)

      

What is causing the error in ghci:

maths.hs:8:21: error:
    * No instance for (Integral Double) arising from a use of `floor'
    * In the expression: floor ((y - x) / dx)
      In an equation for `n': n = floor ((y - x) / dx)
      In an equation for `linspace':
          linspace x dx y
            | y' == y = [x + i * dx | i <- nums]
            | otherwise = ([x + i * dx | i <- nums] ++ [y])
            where
                n = floor ((y - x) / dx)
                nums = [0 .. n]
                y' = (x + (fromIntegral n) * dx)

maths.hs:10:28: error:
    * No instance for (Integral Double)
        arising from a use of `fromIntegral'
    * In the first argument of `(*)', namely `(fromIntegral n)'
      In the second argument of `(+)', namely `(fromIntegral n) * dx'
      In the expression: (x + (fromIntegral n) * dx)
Failed, modules loaded: none.

      

Any help would be greatly appreciated!

+3


source to share


2 answers


This version compiles:

linspace :: Double -> Double -> Double -> [Double]                                                                                                                   
linspace x dx y
    | y' == y   = [x + (fromIntegral i) * dx | i <- nums]
    | otherwise = ([x + (fromIntegral i) * dx | i <- nums] ++ [y])
    where
        n = toInteger $ floor ((y - x) / dx)
        nums = [0..n]
        y' = (x + (fromIntegral n) * dx)

      



What are the changes?

  • As @Alec commented, while floor

    logically is an integer, it is not. You need to use toInteger

    .

  • After that you need to use fromIntegral

    when multiplying i

    and `dex.

+3


source


You bound the result linspace

to [Double]

because of the type annotation. Therefore [x + i * dx | i <- nums]

should create such a list Double

s. x

and dx

should be Double

as they are parameters passed to the function, which are all declared as Double

. But what about i

? It is related to nums

; to i

be Double

, nums

must be [Double]

.

The numbers are defined as

nums = [0..n]

      

Ok nums

- the list is in order. But a list of what? It depends on n

; let's get a look!

n = floor ((y - x) / dx)

      

floor

takes, in a nutshell, yours Double

and creates Integral

. Therefore nums

, this is a list of integrals. This is the error you are getting: there is no instance Integral

for Double

; there is no way for types to work well.



To fix these errors, you must do n

a Double

:

n = fromIntegral $ floor ((y - x) / dx)

      

So your definition y'

must be changed as well:

y' = x + n * dx

      

In a nutshell

linspace :: Double -> Double -> Double -> [Double]
linspace x dx y
    | y' == y   = [x + i * dx | i <- nums]
    | otherwise = ([x + i * dx | i <- nums] ++ [y])
    where
        n = fromIntegral $ floor ((y - x) / dx)
        nums = [0.. n]
        y' = (x + n * dx)

      

+5


source







All Articles