【问题标题】:Unification & Substitution统一与替代
【发布时间】:2012-11-07 02:45:24
【问题描述】:

在 Haskell 中,我使用单个构造函数 S :: [(String, a)] -> Subst a 定义了一个多态数据类型 Subst a,如下所示:

data Subst a where
    S :: [(String, a)] -> Subst a
    deriving (Show)

我想定义一个函数get::String -> Subst a -> Maybe a,它接受一个变量名和一个替换,并返回该变量必须被替换的值。如果没有在变量上定义替换,函数应该返回 Nothing。

我尝试了以下方法:

get :: String -> Subst a -> Maybe a
get str (S[]) = Nothing
get str (S((a,b):xs)) = if str == a then Just b
    else get str xs

但我遇到了错误。任何想法为什么?

【问题讨论】:

  • 您有任何理由使用 GADT 语法吗?你不能把你的类型写成data Subst a = S [(String, a)] deriving Show吗?
  • @Tikhon 实际上没有什么特别的原因,我正在尝试两种方式作为一种学习机制,看看它是否不同
  • 我建议使用Map String a 而不是[(String,a)]。查找列表需要 O(n) 而查找 maps 需要 O(log n)
  • +1 @PetrPudlák 建议。即使您不关心性能,Map a b 类型也有非常丰富的用于查找和插入的 API。

标签: haskell substitution unification


【解决方案1】:
get str (S((a,b):xs)) = if str == a then Just b
    else get str xs

xs[(String, a)] 类型的列表,但get 的第二个参数必须是Subst a。如果您使用构造函数来构造正确类型的值,它会起作用,

get str (S((a,b):xs)) = if str == a then Just b
    else get str (S xs)

但是直接使用列表查找变量更简单,

Prelude> :t lookup
lookup :: Eq a => a -> [(a, b)] -> Maybe b

所以

get str (S xs) = lookup str xs

完全按照你的意愿去做。

【讨论】:

  • 谢谢!我最初使用的是查找功能,但它给我带来了错误,所以我尝试自己编写,但感谢您清除它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-09
  • 2010-10-03
  • 1970-01-01
  • 2018-12-19
  • 2013-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多