简体   繁体   English

制作对象 Haskell

[英]Making an Object Haskell

Hey Everyone I am trying to make Neuron as an Object that is a list of 3 doubles after declaration, however when I try to write the recall method, it says • Couldn't match expected type '[Double]' with actual type 'Neuron', anyone knows where the problem is thanks in advance大家好,我正在尝试将 Neuron 作为一个对象,该对象是声明后 3 个双打的列表,但是当我尝试编写召回方法时,它说 • 无法将预期类型 '[Double]' 与实际类型 'Neuron 匹配',任何人都知道问题出在哪里提前谢谢

-- simple neuron
data Neuron = Neuron [Double]
      deriving (Read,Show)

recall :: Neuron -> [Double] -> Double
recall ws xs = y
 where y = sum (zipWith (*) ws (-1:xs))

Neuron is not the same thing as [Double] ; Neuron[Double]不是一回事; it is instead a wrapper around [Double] .相反,它是[Double]的包装器。 Thus you must unwrap the value before you can use it like a list:因此,您必须先解开该值,然后才能像列表一样使用它:

recall :: Neuron -> [Double] -> Double
recall (Neuron ws) xs = y
    where y = sum (zipWith (*) ws (-1:xs))

Though I have another issue with your code.虽然我对你的代码有另一个问题。 In this example, since you know that a Neuron must wrap a list of specifically 3 Double s, you should enforce that with the type system, instead defining Neuron as:在这个例子中,因为你知道一个Neuron必须包含一个特定的 3 个Double的列表,你应该用类型系统来强制它,而不是将Neuron定义为:

newtype Neuron = Neuron (Double, Double, Double)
    deriving (Read, Show)

recall :: Neuron -> [Double] -> Double
recall (Neuron (w1, w2, w3)) xs = y (xs ++ repeat 0)
    where y (x2:x3:_) = w1 * (-1) + w2 * x2 + w3 * x3

Yes, you lose out on using zipWith and sum , but that's really just obscuring a simpler underlying calculation.是的,您失去了使用zipWithsum ,但这实际上只是掩盖了更简单的基础计算。 There's no need to use generic functions when only one specific case will ever be used.当只使用一种特定情况时,就没有必要使用泛型函数。

Note also the use of newtype instead of data .还要注意使用newtype而不是data newtype gives you potentially more performant derived implementations of Read and Show and also provides access to advanced tools like Generalized Newtype Deriving, which you may not care about now, but later may be very useful. newtype为您提供了潜在更高性能的ReadShow派生实现,还提供了对 Generalized Newtype Deriving 等高级工具的访问,您现在可能不关心,但以后可能会非常有用。 In general, using newtype instead of data for datatypes that just wrap another datatype is a good habit to get into.通常,对于仅包装另一种数据类型的data类型,使用newtype而不是data是一个好习惯。

In a comment, @leftroundabout also mentions that if the data do not naturally form a tuple or vector, you should not wrap a tuple, in which case the code would look like this:在评论中,@leftroundabout 还提到如果数据不是自然形成元组或向量,则不应包装元组,在这种情况下,代码将如下所示:

data Neuron = Neuron { property1 :: Double
                     , property2 :: Double
                     , property3 :: Double
                     } deriving (Read, Show)

recall :: Neuron -> [Double] -> Double
recall (Neuron w1 w2 w3) xs = y (xs ++ repeat 0)
    where y (x2:x3:_) = w1 * (-1) + w2 * x2 + w3 * x3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM