首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >非monad如何使用` `bound` `?

非monad如何使用` `bound` `?
EN

Stack Overflow用户
提问于 2020-09-02 01:22:06
回答 1查看 64关注 0票数 3

我正在尝试使用bound package在一种简单的逻辑语言中表示术语和命题。这是我到目前为止所知道的:

代码语言:javascript
复制
import Bound

data Term a = V a
            | Func String [Term a]
  deriving (Eq, Ord, Read, Show, Functor, Foldable, Traversable)

data Prop a = And (Prop a) (Prop a)
            | Relation String [Term a]
            | Forall (Scope () Prop a)
            deriving (Functor, Foldable, Traversable)

特别地,有一些术语既可以是变量,也可以是应用于某些术语的函数,也可以是命题:两个命题的合取,应用于某些术语的关系,以及对另一个命题中变量的量化。但是,当我尝试创建一个函数来构造一个"Forall“时,按照包文档中的示例,我被告知Prop不是monad:

代码语言:javascript
复制
forall' :: Eq a => a -> Prop a -> Prop a
forall' v b = Forall (abstract1 v b)

这是意料之中的,因为我没有定义Monad Prop。但是Prop中没有合理的pure (或return),那么如何使用bound包来支持这种语言呢?

EN

回答 1

Stack Overflow用户

发布于 2020-09-02 02:37:06

我认为你只需要在这里合并TermProp

代码语言:javascript
复制
data Exp a
  = V a
  | Func String [Exp a]
  | And (Exp a) (Exp a)
  | Relation String [Exp a]
  | Forall (Scope () Prop a)

如果我没理解错的话,abstract1想要的Applicative/Monad结构应该是让pure注入一个变量,然后由>>=进行替换。这样,您的ApplicativeMonad实例就可以直接遵循文档:

代码语言:javascript
复制
instance Applicative Exp where
  pure = V
  (<*>) = ap

instance Monad Exp where
  return = V
  V a           >>= f = f a
  And x y       >>= f = And (x >>= f) (y >>= f)
  Relation r xs >>= f = Relation r (fmap (>>= f) xs)  -- (I think.)
  Forall e      >>= f = Forall (e >>>= f)             -- NB: bound’s ‘>>>=’.

您可以根据您的用例以不同的方式重新安排:

  • 向包装单个TermProp添加构造函数:

数据属性a= And (属性a) (属性a) |关系字符串项a|全部(作用域()属性a) |项(术语a)

  • 使Exp成为TermProp的总和,并为此实现ApplicativeMonad

数据扩展a= Term (Term a) | Prop (Prop a)

  • 使Exp成为一个GADT,通过它是一个原子术语还是一个通用命题来索引:

{-# LANGUAGE DataKinds,GADTs,KindSignatures #-}数据类=原子|复合数据Exp (c ::Class) a其中V ::a ->术语函数::String ->术语->术语a和::支持->属性->属性a关系::String ->术语->属性Forall ::Scope ()支持->属性类型术语a= Exp‘原子类型属性a= Exp’复合

  • 使用智能构造函数为Exp的“子类型”制作newtype包装器,如果您只需要区分它们的话:

新类型术语a=术语(Exp a)新类型prop a=属性(Exp a)术语::Exp a ->可能(术语a)术语t=案例t of V{} -> yes Func{} -> yes _ -> no where yes = Just (术语t) no = Nothing属性::Exp a ->可能(属性a)属性t=案例t of…

但是无论哪种方式,你都需要V来表达“命题可以是变量”或者“表达式可以是命题也可以是变量”。事实上,我认为你实际上可以用你的类型原样来表达,使用一个虚拟的关系:pure a = Relation "" [V a],但是这些其他形式中的一种可能更简洁。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63692563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档