尝试为函数实现类型类

问题描述 投票:0回答:1

我正在尝试为函数类型实现类型类:

{-# LANGUAGE FlexibleInstances #-}

module Match where

import Tokens (Token (..))

class Match a where
    match :: (Match b) => a -> [Token] -> Either String b

instance Match (Int -> b) where
    match = matchInt

matchInt :: (Match b) => (Int -> b) -> [Token] -> Either String b
matchInt fn (Number i : ts) = match (fn i) ts
matchInt _ _ = Left "missing integer argument"

我在构建时不断收到以下错误,我不明白我做错了什么:

error: [GHC-25897]
    • Couldn't match type ‘b1’ with ‘b’
      Expected: (Int -> b) -> [Token] -> Either String b1
        Actual: (Int -> b) -> [Token] -> Either String b
      ‘b1’ is a rigid type variable bound by
        the type signature for:
          match :: forall b1.
                   Match b1 =>
                   (Int -> b) -> [Token] -> Either String b1
        at src/Match.hs:11:5-9
      ‘b’ is a rigid type variable bound by
        the instance declaration
        at src/Match.hs:10:10-25
    • In the expression: matchInt
      In an equation for ‘match’: match = matchInt
      In the instance declaration for ‘Match (Int -> b)’
    • Relevant bindings include
        match :: (Int -> b) -> [Token] -> Either String b1
          (bound at src/Match.hs:11:5)
   |
11 |     match = matchInt
   |             ^^^^^^^^

我不想更改类型类以显式引用函数。那是因为我希望能够实现非函数的类型类。 (这个想法是,您可以传递一个类型构造函数来与标记列表一起匹配,它会吐出完全构造的类型或错误)

haskell typeclass
1个回答
0
投票

此错误通常是由类型不匹配引起的。 在您的代码中,定义的 match 函数的类型签名为 (Int-> b)-> [Token]-> Either String b1,而实例中的 matchInt 函数的类型为 (Int-> b)-> [Token ]-> 任一字符串 b. 这里b1和b被视为不同类型的变量,导致类型不匹配错误。 要解决这个问题,需要确保match函数和matchInt函数的类型完全相同,即它们都使用相同类型的变量b。您可能需要检查函数的实现和类型声明,以确保它们在类型上协调一致。

© www.soinside.com 2019 - 2024. All rights reserved.