输入 类、实例和包装器

Type classes, instances and wrappers

有人可以向我解释为什么这个(版本 1)可以编译而下面的版本(版本 2)不能编译。

-- version 1 (compiles)
module Chapter2 where

import Debug.Trace

data Wrapper a = Wrapper a
instance showWrapper :: (Show a) => Show (Wrapper a) where
    show (Wrapper w) = "Wrapper ( " ++ (show w) ++ " )"

foo :: Number -> Number -> Number -> Number
foo a b c = a + b + c
foo1 = foo 2
foo2 = foo 1 2

class ExecFn a where
    exec :: a -> Number

instance execFn1 :: ExecFn (Number -> Number -> Number) where
    exec a = 99

main = do
    let x = exec foo1
    trace "Hello"

这不编译

-- Version 2 (does not compile)
module Chapter2 where

import Debug.Trace

data Wrapper a = Wrapper a
instance showWrapper :: (Show a) => Show (Wrapper a) where
    show (Wrapper w) = "Wrapper ( " ++ (show w) ++ " )"

foo :: Number -> Number -> Number -> Number
foo a b c = a + b + c
foo1 = foo 2
foo2 = foo 1 2

class ExecFn a b where
    exec :: a -> Wrapper b

instance execFn1 :: ExecFn (Number -> Number -> Number) Number where
    exec a = Wrapper 99

main = do
    let x = exec foo1
    trace "Hello"    

并给我这个错误

Error at src/Chapter2.purs line 3, column 1 - line 5, column 1:
  No instance found for Chapter2.ExecFn (Prim.Number -> Prim.Number -> Prim.Number) u8735

那么我怎样才能制作一个类似于我的版本 2 的版本,以便我可以将我的结果放入包装器中?

x的类型是underconstrained,这就是错误信息中出现未知类型变量的原因。 psc 在搜索类型 class 实例时不会尝试实例化类型变量。当使用多参数类型 classes 而没有诸如功能依赖之类的东西来帮助消除类型歧义时,这有时会成为一个问题(例如,purescript-transformers 有同样的问题)。现在,您需要添加类型签名,或者以消除类型 b.

歧义的方式使用 x

因此,如果您为 let

添加预期的类型
let x = exec foo1 :: Wrapper Number

这应该有帮助