Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图在haskell中将列表相乘_Haskell - Fatal编程技术网

试图在haskell中将列表相乘

试图在haskell中将列表相乘,haskell,Haskell,自从老师强迫我们学习哈斯克尔以来,我一直在学习。 作为练习,我们将尝试编写一个近似sin(x)函数的解决方案,使用Maclaurin级数直到第30项 我想到了用列表来表示1和-1的交替序列,将x提升为奇数,以及奇数的阶乘。然后,我将前两个列表相乘,最后一个列表相除。到目前为止,我只写了以下内容: oddl = [1,3..] powerl x = map (x^) oddl factorial 0 = 1 factorial x = factorial (x - 1) * x factl = m

自从老师强迫我们学习哈斯克尔以来,我一直在学习。 作为练习,我们将尝试编写一个近似sin(x)函数的解决方案,使用Maclaurin级数直到第30项

我想到了用列表来表示1和-1的交替序列,将x提升为奇数,以及奇数的阶乘。然后,我将前两个列表相乘,最后一个列表相除。到目前为止,我只写了以下内容:

oddl = [1,3..]
powerl x = map (x^) oddl
factorial 0 = 1
factorial x = factorial (x - 1) * x
factl = map factorial oddl
alterl = scanl (*) (-1) [-1,-1..]
sined x = zipWith (*) (powerl x) alterl
sinex x = zipWith (/) sined factl
sinf x = foldl (+) (take 30 (sinex x))
然后在
ghci
中,我将输入
sinf 3.14
,但在加载后输入之前,我得到以下信息:

exert.hs:31:8:
    No instance for (Enum t0)
      arising from the arithmetic sequence ‘1, 3 .. ’
    The type variable ‘t0’ is ambiguous
    Relevant bindings include oddl :: [t0] (bound at exert.hs:31:1)
    Note: there are several potential instances:
      instance forall (k :: BOX) (s :: k). Enum (Data.Proxy.Proxy s)
        -- Defined in ‘Data.Proxy’
      instance Integral a => Enum (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      instance Enum Ordering -- Defined in ‘GHC.Enum’
      ...plus 8 others
    In the expression: [1, 3 .. ]
    In an equation for ‘oddl’: oddl = [1, 3 .. ]

exert.hs:31:9:
    No instance for (Num t0) arising from the literal ‘1’
    The type variable ‘t0’ is ambiguous
    Relevant bindings include oddl :: [t0] (bound at exert.hs:31:1)
    Note: there are several potential instances:
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      instance Num Integer -- Defined in ‘GHC.Num’
      instance Num Double -- Defined in ‘GHC.Float’
      ...plus three others
    In the expression: 1
    In the expression: [1, 3 .. ]
    In an equation for ‘oddl’: oddl = [1, 3 .. ]

exert.hs:32:18:
    Could not deduce (Integral t0) arising from a use of ‘^’
    from the context (Num b)
      bound by the inferred type of powerl :: Num b => b -> [b]
      at exert.hs:32:1-24
    The type variable ‘t0’ is ambiguous
    Note: there are several potential instances:
      instance Integral Integer -- Defined in ‘GHC.Real’
      instance Integral Int -- Defined in ‘GHC.Real’
      instance Integral Word -- Defined in ‘GHC.Real’
    In the first argument of ‘map’, namely ‘(x ^)’
    In the expression: map (x ^) oddl
    In an equation for ‘powerl’: powerl x = map (x ^) oddl

exert.hs:35:13:
    No instance for (Eq t0) arising from a use of ‘factorial’
    The type variable ‘t0’ is ambiguous
    Relevant bindings include factl :: [t0] (bound at exert.hs:35:1)
    Note: there are several potential instances:
      instance (Eq a, Eq b) => Eq (Either a b)
        -- Defined in ‘Data.Either’
      instance forall (k :: BOX) (s :: k). Eq (Data.Proxy.Proxy s)
        -- Defined in ‘Data.Proxy’
      instance (GHC.Arr.Ix i, Eq e) => Eq (GHC.Arr.Array i e)
        -- Defined in ‘GHC.Arr’
      ...plus 28 others
    In the first argument of ‘map’, namely ‘factorial’
    In the expression: map factorial oddl
    In an equation for ‘factl’: factl = map factorial oddl

exert.hs:38:23:
    Couldn't match expected type ‘[t0]’
                with actual type ‘Integer -> [Integer]’
    Relevant bindings include
      sinex :: t -> [t0] (bound at exert.hs:38:1)
    Probable cause: ‘sined’ is applied to too few arguments
    In the second argument of ‘zipWith’, namely ‘sined’
    In the expression: zipWith (/) sined factl

exert.hs:39:16:
    Could not deduce (Num [t0]) arising from a use of ‘+’
    from the context (Foldable t)
      bound by the inferred type of
               sinf :: Foldable t => t1 -> t [t0] -> [t0]
      at exert.hs:39:1-38
    The type variable ‘t0’ is ambiguous
    Relevant bindings include
      sinf :: t1 -> t [t0] -> [t0] (bound at exert.hs:39:1)
    In the first argument of ‘foldl’, namely ‘(+)’
    In the expression: foldl (+) (take 30 (sinex x))
    In an equation for ‘sinf’: sinf x = foldl (+) (take 30 (sinex x))
Failed, modules loaded: none.
这么多信息。哇! 我不知道自己做错了什么,甚至不知道从哪里开始阅读信息。 有人能解释一下吗?实际上,作为一个初学者,我很好奇Haskell的错误是什么,以及是什么阻止了它的工作

编辑:添加类型签名和缺少的参数后。

oddl :: [Integer]
oddl = [1,3..]
powerl :: Integer -> [Integer]
powerl x = map (x^) oddl
factorial 0 = 1
factorial x = factorial (x - 1) * x
factl :: [Integer]
factl = map factorial oddl
alterl = scanl (*) (-1) [-1,-1..]
sined x = zipWith (*) (powerl x) alterl
sinex x = zipWith (/) (sined x) factl
sinf x = foldl (+) (take 30 (sinex x))
现在我得到一个较短的错误:

exert.hs:41:19:
    No instance for (Fractional Integer) arising from a use of ‘/’
    In the first argument of ‘zipWith’, namely ‘(/)’
    In the expression: zipWith (/) (sined x) factl
    In an equation for ‘sinex’: sinex x = zipWith (/) (sined x) factl

exert.hs:42:16:
    Could not deduce (Num [Integer]) arising from a use of ‘+’
    from the context (Foldable t)
      bound by the inferred type of
               sinf :: Foldable t => Integer -> t [Integer] -> [Integer]
      at exert.hs:42:1-38
    In the first argument of ‘foldl’, namely ‘(+)’
    In the expression: foldl (+) (take 30 (sinex x))
    In an equation for ‘sinf’: sinf x = foldl (+) (take 30 (sinex x))

Haskell中的数字与类型和类型推断有很多关系,因此对于初学者来说,它们可能很棘手。不允许使用
/
运算符对整数进行除法(有
`div`
用于截断整数除法)。如何使常数成为整数也可能相当棘手,因为这取决于它的使用方式(稍后!)1。但您需要了解的主要内容是
fromIntegral
函数,它将整数转换为任何其他数值类型

ghci> let x = 10 :: Integer
ghci> x / 5
<interactive>:6:1: error:
    • No instance for (Fractional Integer) arising from a use of ‘/’
    • In the expression: x / 5
      In an equation for ‘it’: it = x / 5
ghci> fromIntegral x / 5
2.0
oddl
必须是整数列表<代码>(*)返回与其参数相同的类型(必须是相同的类型),因此我们从

powerl x = map (x^) oddl
factorial x = factorial (x - 1) * x
factorial返回与其参数相同的类型,因此

factl = map factorial oddl
还必须是整数列表。那么我们有

sinex x = zipWith (/) sined factl

它现在将整数作为
(/)
的参数,这是不合法的

编辑后,查看第一个错误:

No instance for (Fractional Integer) arising from a use of ‘/’
(/)
的类型为:

(/) :: Fractional a => a -> a -> a
因此,它接受两个
a
类型的值,它们必须是
分数
,并返回同一类型
a
的结果
Integer
不是
fractal
——这里有整数除法函数
div
quot
(以及它们的余数对应项
mod
rem
),但这不是您想要的,因为您想要的是分数结果。解决方案是使用
from integral
将整数参数转换为分数类型,例如
Double

fromIntegral :: (Num b, Integral a) => a -> b

fromIntegral (x :: Integer) :: Double  -- or ‘… :: Float’
例如,您可以编写
sum xs/from integral(length xs)
来获得
Double
列表的平均值

第二个错误:

Could not deduce (Num [Integer]) arising from a use of ‘+’
源于此表达式:

foldl (+) (take 30 (sinex x))

foldl
接受三个参数:缩减函数、起始值和输入容器;您试图将容器作为起始值传递,因此
foldl
尝试对未定义的整数列表调用
+
。您可能需要
foldl(+)0
sum

这里有一个更合理的方法来编写所有内容:

sinf :: Double -> Double
sinf x = sum $ take 30
           [ sign * power / fact
           | (sign, power, fact) <- zip3
               (iterate negate 1)
               (oddEntries $ iterate (*x) 1)
               (oddEntries factorials) ]
 where factorials :: [Double]
       factorials = scanl (*) 1 [1..]

oddEntries :: [a] -> [a]
oddEntries (_:x:xs) = x : oddEntries xs
oddEntries _ = []
这里,typechecker自动做正确的事情,并为阶乘列表(以及符号列表)选择类型
Double
,因为上下文需要
Double
。(但为了便于阅读,最好还是给它起一个本地名称和签名。)


实际上,您只需在零附近的小范围内使用Maclaurin级数,并利用周期性定义实轴其余部分的函数:

sinf :: Double -> Double
sinf x = sum $ take 30
           [ sign * power / fact
           | (sign, power, fact) <- zip3
               (iterate negate 1)
               (oddEntries $ iterate (*x') 1)
               (oddEntries factorials) ]
 where factorials :: [Double]
       factorials = scanl (*) 1 [1..]
       x' = x - 2*pi*fromIntegral (round $ x/(2*pi))
sinf::Double->Double
sinf x=总计$30
[签名*权力/事实]

|(签名、权力、事实)始终写出类型签名。(这可能不会解决您的问题,但它肯定会大大降低错误消息的神秘性。)我可能不想在这里问这个问题,但类型签名到底是什么?那一行是“:”?@user3076623是的,完全正确。不相关,但是
alterl=iterate-negate 1
感觉更好concise@RegisKuckaertz我认为,
alterl=cycle[1,-1]
更清楚。但是fromIntegral只适用于单个值,对吗?@user3076623,是的,但它是一个常规函数,所以你可以
映射它。我可能更愿意做一个小助手,尽管
divInts x y=fromIntegral x/fromIntegral y
来进行压缩。所以它就像“sined x=map(fromIntegral)(zipWith(*)(powerl x)alterl)“?@user3076623,在我看来是正确的(用integral中的
多余参数进行模运算)事实上,你的建议是有效的!我的意思是第一个。
$ ghci wtmpf-file3770.hs 
GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Loaded GHCi configuration from /home/sagemuej/.ghci
[1 of 1] Compiling Main             ( wtmpf-file3770.hs, interpreted )
Ok, 1 module loaded.
*Main> :m +Graphics.Dynamic.Plot.R2 
*Main Graphics.Dynamic.Plot.R2> plotWindow [legendName "sin" $ continFnPlot sin, legendName "sinf" $ continFnPlot sinf]
sinf :: Double -> Double
sinf x = sum $ take 30
           [ sign * power / fact
           | (sign, power, fact) <- zip3
               (iterate negate 1)
               (oddEntries $ iterate (*x') 1)
               (oddEntries factorials) ]
 where factorials :: [Double]
       factorials = scanl (*) 1 [1..]
       x' = x - 2*pi*fromIntegral (round $ x/(2*pi))