2

所以这是我在 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) 时,我经常遇到类型错误。如果不掌握何时可以进行推理,何时不能进行推理,则培养诊断和理解这些错误的技能是一项挑战。否则我将不得不每次都编写类型以对我的代码充满信心(跛足)。

4

1 回答 1

3

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

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

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

在您的第二点上,无论如何,输入顶级声明被认为是一种很好的风格,因为它有助于记录您的代码:请参阅此处以获得更完整的解释

于 2014-07-26T00:54:18.883 回答