无法使用数据变量定义实例方法

时间:2015-03-19 04:22:04

标签: haskell module

首先,我试图解决相互递归模块问题。但是,我解决这个问题的努力使代码变得更糟。

原始问题

我有两个模块,如

module W where

import T

data W = W  { wName  :: String
            , queue  :: [T W]}`

module T where

import W

data T = T { tName  :: String
            , tUpdate :: W -> IO W}

class Manage a where
    update :: a -> W -> IO W

instance Manage T where
    update = tUpdate

由于相互递归的模块问题,这些模块无法工作。

所以我根据this link

更改了module T

具有数据变量的新解决方案

module T where

data T w = T { tName  :: String
            , tUpdate :: w -> IO w}

class Manage a where
    update :: a -> w -> IO w

instance Manage (T w) where
    update = tUpdate

但是,此代码会产生如下错误:

Couldn't match type ‘w’ with ‘w1’
  ‘w’ is a rigid type variable bound by
      the instance declaration at TestModule2.hs:12:10
  ‘w1’ is a rigid type variable bound by
       the type signature for update :: T w -> w1 -> IO w1
       at TestModule2.hs:13:5
Expected type: T w -> w1 -> IO w1
  Actual type: T w -> w -> IO w
Relevant bindings include
  update :: T w -> w1 -> IO w1 (bound at TestModule2.hs:13:5)
In the expression: tUpdate
In an equation for ‘update’: update = tUpdate

所以,我尝试了很多东西来解决这个问题,比如

引入新的类State w来代表data W

要解决rigid type variable ...,我引入了新课程。

{-# LANGUAGE InstanceSigs, Rank2Types #-}
module T where

.....

data T w = T  { tName  :: String
              , tUpdate :: (State w) => w -> IO w}

class Manage a where
    update :: (State w) => a -> (w -> IO w)

instance (State w) => Manage (T w) where
    update :: T w -> w -> IO w
    update = tUpdate

但是这段代码也会出现错误:

Method signature does not match class; it should be
  update :: forall w1. State w1 => T w -> w1 -> IO w1
In the instance declaration for ‘Manage (T w)’

我遵循了这个建议,但这不起作用。 此外,w1w应该是相同的类型。

我是否需要以其他方式定义类或类方法?

那么,我需要学习什么以及如何解决这个问题?

我尝试了更多的东西,但我无法解决这个问题。 我需要学习什么才能解决这个问题? 我怎么能解决这个问题?

要点:

  1. 我需要将这两个模块分开。
  2. 尽可能地,我不想使用hs-boot,但更优雅的方式

1 个答案:

答案 0 :(得分:1)

根据user2407038条评论,一个解决方案可以是:

模块T:

module T where

data T w = T { tName   :: String
             , tUpdate :: w -> IO w
             }

class Manage a where
    update :: a w -> w -> IO w

instance Manage T where
    update = tUpdate

模块W:

module W where

import T

data W = W { wName :: String
           , queue :: [T W]
           }