函数不能使用类型推断,但我不明白为什么

时间:2014-07-25 23:15:08

标签: functional-programming purescript

所以这是我的傻瓜沙盒与PureScript中的Applicatives一起玩

module Main where

import Debug.Trace

data Foo a
   = Foo a

instance showFoo :: (Show a) => Show (Foo a) where
  show (Foo a) = "I pity da (Foo " ++ (show a) ++ ")"

instance functorFoo :: Functor Foo where
  (<$>) f (Foo a) = Foo (f a)

instance applyFoo :: Apply Foo where
  (<*>) (Foo a) (Foo b) = Foo (a b)

m :: Number -> Number -> Number -> Number
m x y z = x * y - z

main = trace <<< show $ m <$> Foo 14
                          <*> Foo 2
                          <*> Foo 5

以上工作正常,但如果我删除:

m :: Number -> Number -> Number -> Number

它无法编译

Error at pure.purs line 18, column 1: 
Error in declaration m
No instance found for Prelude.Num u1150

(+)(-)都是

类型
forall a. (Prelude.Num a) => a -> a -> a

为什么不能推断Number


现实情况是,在学习PureScript并使用动态语言(JavaScript)时,我会经常遇到类型错误。培养诊断和理解这些错误的技能具有挑战性,而无需掌握何时可以进行推理以及何时无法进行推理。否则我将不得不每次都写类型以便对我的代码(跛足)充满信心。

1 个答案:

答案 0 :(得分:3)

这是因为目前编译器无法推断出类型类约束,并且正如您所指出的那样,算术运算符都是在Num类型类中定义的。

m推断的类型(如果编译器可以)将类似于:

m :: forall a. (Num a) => a -> a -> a -> a

在第二点输入顶级声明无论如何都被认为是好的风格,因为它有助于记录您的代码:see here for a fuller explanation