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(ad-hoc多态性)中重载相乘[Double]的函数?_Haskell_Overloading - Fatal编程技术网

如何在Haskell(ad-hoc多态性)中重载相乘[Double]的函数?

如何在Haskell(ad-hoc多态性)中重载相乘[Double]的函数?,haskell,overloading,Haskell,Overloading,在Haskell中实现特殊多态性(函数重载)的方法是通过类型类(请参见答案和问题等) 但我正在努力为以下情况定义一个重载的mult(产品)函数: mult: [Double] -> Double -> [Double] mult: Double -> [Double] -> [Double] mult: [Double] -> [Double] -> [Double] 谢谢 (至少,案例1[Double]*Double和案例3[Double]*[Double

在Haskell中实现特殊多态性(函数重载)的方法是通过类型类(请参见答案和问题等)

但我正在努力为以下情况定义一个重载的
mult
(产品)函数:

mult: [Double] -> Double -> [Double]
mult: Double -> [Double] -> [Double]
mult: [Double] -> [Double] -> [Double]
谢谢


(至少,案例1
[Double]*Double
和案例3
[Double]*[Double]
是必要的)。

像往常一样,像“我正在尝试(但没有成功)这个”这样的语句并没有您想要的那么有用:最好包含代码,但如果您从编译器收到错误消息,请告诉我们它是什么!它们很有教育意义,印刷出来是有原因的

我刚刚试过你写的东西,事实上这是你(可能)得到的错误信息:

现在,您可以尝试打开FlexibleContext,但这似乎并不能解决问题。但是,当编译器告诉您在推断类型时遇到问题时,通常情况下,您应该尝试添加一些显式类型,看看这是否有帮助:

*Multiplication> mul (1::Double) [2 :: Double]
[2.0]
基本上,编译器无法确定您想要的
mul
的哪个重载:
1
2
是多态的,可以是任何数字类型,而
mul
现在只有一个合适的重载,编译器不会做出这样的推断,除非它能证明在这个上下文中不可能存在其他重载。完全指定参数类型就足以解决问题

解决此特定问题的另一种方法是对每个参数使用typeclass,将其转换为规范类型
[Double]
,而不是将参数作为一个整体使用typeclass。这是一个比一般的即席多态性更具体的解决方案,并不是所有的问题都适合,但对于像将单个数字视为数字列表这样的问题,应该可以:

module Multiplication where
import Control.Monad (liftM2)

class AsDoubles a where
  doubles :: a -> [Double]

instance AsDoubles Double where
  doubles = return

instance AsDoubles [Double] where
  doubles = id

mult :: (AsDoubles a, AsDoubles b) => a -> b -> [Double]
mult x y = liftM2 (*) (doubles x) (doubles y)

*Multiplication> mult [(1 :: Double)..5] [(1 :: Double)..3]
[1.0,2.0,3.0,      -- whitespace added for readability
 2.0,4.0,6.0,
 3.0,6.0,9.0,
 4.0,8.0,12.0,
 5.0,10.0,15.0]

我已经设法这样做了。当然不是很好

我认为任何人都应该考虑左翼人士的评论和批评,但我要问下面的问题:方便和相关。
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}

class Multipliable ta tb tc | ta tb -> tc where
      mul :: ta -> tb -> tc

instance Multipliable [Double] Double [Double] where
          mul p k = map (*k) p --mul p k = map (\a -> k * a) p

instance Multipliable Double [Double] [Double] where
          mul k p = map (*k) p --mul p k = map (\a -> k * a) p

instance Multipliable [Double] [Double] [Double] where
         mul p q = p  -- dummy implementation


r = [1.0, 2.0, 3.0]  :: [Double]


r1 = (mul :: [Double] -> Double -> [Double]) r 2.0 

r2 = (mul :: Double -> [Double] -> [Double]) 2.0 r

r3 = (mul :: [Double] -> [Double] -> [Double]) r1 r2


main = do
     print r1
     print r2
     print r3

你为什么要这个?只是因为Matlab允许乘法 你扔给它的任何东西都不意味着这是个好主意。退房 向量空间的正确处理 多维乘法。或者,如果你不在乎的话 为了数学上的优雅,您可以使用hmatrix(实际上是 很像Haskell中的Matlab/Octave),或线性

我认为这通常是一个坏主意,在Haskell中确实没有必要,因为您可以只编写
map(*x)ys
zipWith(*)xs ys
使你的意图明确。这当然对我不起作用 应该同时处理标量和向量的多态代码—— 然而,编写这样的代码只是为了处理标量或任何 长度相当于自找麻烦。很难具体说明是哪一个 列表需要有一个与其他列表和长度相匹配的长度 结果将是等等。。这就是向量空间或线性的光芒所在, 因为它们在编译时检查维度


我想你错了,我想有人纠正“我的代码”。我只想要这个问题的一般解决方案(如果有的话)。忘记密码吧。我的便条只是为了表明我不是在等待任何人来做这项工作。谢谢你的回答。我要试试,你为什么要这个?只是因为。检查是否正确处理多维乘法。或者,如果你不太在意数学的优雅,你可以使用(实际上很像Haskell中的Matlab/Octave),或者@leftaroundabout谢谢你的链接。你是说这种多态性不是一个好主意吗(不仅仅是matlab允许的)?这是一个“一般”的坏主意还是在Haskell中?好吧,我认为这是一个一般的坏主意,在Haskell中确实没有必要,因为你可以只写
map(*x)ys
zipWith(*)xs ys
,让你的意图明确。这当然不适用于应该同时处理标量和向量的多态代码——然而,编写这样的代码来处理标量或任意长度的列表相当麻烦。很难指定哪个列表的长度需要与其他列表的长度匹配,以及结果的长度等。。这就是
向量空间
线性
的亮点所在,因为它们在编译时检查维度。@leftaroundabout感谢您的帮助。
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}

class Multipliable ta tb tc | ta tb -> tc where
      mul :: ta -> tb -> tc

instance Multipliable [Double] Double [Double] where
          mul p k = map (*k) p --mul p k = map (\a -> k * a) p

instance Multipliable Double [Double] [Double] where
          mul k p = map (*k) p --mul p k = map (\a -> k * a) p

instance Multipliable [Double] [Double] [Double] where
         mul p q = p  -- dummy implementation


r = [1.0, 2.0, 3.0]  :: [Double]


r1 = (mul :: [Double] -> Double -> [Double]) r 2.0 

r2 = (mul :: Double -> [Double] -> [Double]) 2.0 r

r3 = (mul :: [Double] -> [Double] -> [Double]) r1 r2


main = do
     print r1
     print r2
     print r3