定义向量的函数在Haskell中不起作用

Nik*_*ola 1 haskell function

我是Haskell的初学者(目前正在学习模式匹配),我尝试编写简单的函数来定义向量:

vector :: (Num a) => a -> a -> String
vector 0 0 = "This vector has 0 magnitude."
vector x y = "This vector has a magnitude of " ++ show(sqrt(x^2 + y^2)) ++ "."
Run Code Online (Sandbox Code Playgroud)

但是我得到了许多我根本不理解的错误.

helloworld.hs:9:8: error:
    • Could not deduce (Eq a) arising from the literal ‘0’
      from the context: Num a
        bound by the type signature for:
                   vector :: Num a => a -> a -> String
        at helloworld.hs:8:1-37
      Possible fix:
        add (Eq a) to the context of
          the type signature for:
            vector :: Num a => a -> a -> String
    • In the pattern: 0
      In an equation for ‘vector’:
          vector 0 0 = "This vector has 0 magnitude."

helloworld.hs:10:51: error:
    • Could not deduce (Show a) arising from a use of ‘show’
      from the context: Num a
        bound by the type signature for:
                   vector :: Num a => a -> a -> String
        at helloworld.hs:8:1-37
      Possible fix:
        add (Show a) to the context of
          the type signature for:
            vector :: Num a => a -> a -> String
    • In the first argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2))’
      In the second argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2)) ++ "."’
      In the expression:
        "This vector has a magnitude of "
        ++ show (sqrt (x ^ 2 + y ^ 2)) ++ "."

helloworld.hs:10:56: error:
    • Could not deduce (Floating a) arising from a use of ‘sqrt’
      from the context: Num a
        bound by the type signature for:
                   vector :: Num a => a -> a -> String
        at helloworld.hs:8:1-37
      Possible fix:
        add (Floating a) to the context of
          the type signature for:
            vector :: Num a => a -> a -> String
    • In the first argument of ‘show’, namely ‘(sqrt (x ^ 2 + y ^ 2))’
      In the first argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2))’
      In the second argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2)) ++ "."’
Failed, modules loaded: none.
Prelude> :load helloworld
[1 of 1] Compiling Main             ( helloworld.hs, interpreted )

helloworld.hs:10:51: error:
    • Could not deduce (Show a) arising from a use of ‘show’
      from the context: Integral a
        bound by the type signature for:
                   vector :: Integral a => a -> a -> String
        at helloworld.hs:8:1-42
      Possible fix:
        add (Show a) to the context of
          the type signature for:
            vector :: Integral a => a -> a -> String
    • In the first argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2))’
      In the second argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2)) ++ "."’
      In the expression:
        "This vector has a magnitude of "
        ++ show (sqrt (x ^ 2 + y ^ 2)) ++ "."

helloworld.hs:10:56: error:
    • Could not deduce (Floating a) arising from a use of ‘sqrt’
      from the context: Integral a
        bound by the type signature for:
                   vector :: Integral a => a -> a -> String
        at helloworld.hs:8:1-42
      Possible fix:
        add (Floating a) to the context of
          the type signature for:
            vector :: Integral a => a -> a -> String
    • In the first argument of ‘show’, namely ‘(sqrt (x ^ 2 + y ^ 2))’
      In the first argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2))’
      In the second argument of ‘(++)’, namely
        ‘show (sqrt (x ^ 2 + y ^ 2)) ++ "."’
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

有人可以解释我如何正确编写这个功能,至少有什么问题vector 0 0

Sar*_*rah 5

第一个类型错误是因为您在文字上进行了模式匹配0.您只需要Num a您需要的地方(Num a, Eq a),以便实现这一目标.

第二种类型的错误是因为你试图在涉及你的计算中使用show a.所以现在,你需要(Num a, Eq a, Show a).

第三个,因为你已经使用了sqrt,它不存在于Num但是Floating现在也是如此(Num a, Eq a, Show a, Floating a).

或者,您可以完全删除类型签名并提示ghci类型:

?> :t vector
vector :: (Show a, Floating a, Eq a) => a -> a -> [Char]
Run Code Online (Sandbox Code Playgroud)

注意Floating暗示Num.