在Haskell中实现一种语言:同源列表

时间:2015-12-17 23:19:47

标签: list haskell interpreter

我正在尝试为haskell中的函数式语言创建一个解释器(我是该语言的新手)。我正在创造可能是极简主义和便利的奇怪组合 - 没有抽象数据类型,但我想提供制作同类列表的能力。

所以我的基本变量是> n <- 8 > set.seed(17) > x <- replicate(1e6, sample(1:n, n)) > > paired <- function(x) crossprod(x[x] - 1:length(x))==0 > paired2 <- function(x) sum(x[x]==1:length(x))==length(x) > paired3 <- function(x) sum(abs(x[x]-1:length(x)))==0 > > system.time(i.paired <- apply(x, 2, paired)) user system elapsed 9.812 0.000 9.821 > system.time(i.paired2 <- apply(x, 2, paired2)) user system elapsed 4.548 0.000 4.550 > system.time(i.paired3 <- apply(x, 2, paired3)) user system elapsed 4.617 0.000 4.617 > > all.equal(i.paired,i.paired2) [1] TRUE > all.equal(i.paired,i.paired3) [1] TRUE ,我意识到我完全不确定如何表示同类列表。添加构造函数data Datum = DatInt Int | DatDbl Double | DatBool Bool或类似的东西将构成异构列表,并为每种类型创建单独的列表,即List Datum将排除列表列表。

表示同质列表的最佳方法是什么?

1 个答案:

答案 0 :(得分:5)

一个有用的概念(无论你是否适合性感类型)都是类型标签。非性感版本更易于处理。

data Tag = IntTag
         | DoubleTag
         | BoolTag
         | ListTag Tag
   deriving (Eq, Show)

现在您的类型由这些不同的标签表示。 IntIntTag表示。 Int列表由ListTag IntTag表示。

现在您可以表示类似注释的表达式:

data Expr = IntLit Int
          | DoubleLit Double
          | BoolLit Bool
          | ListLit Tag [Expr]

-- Check that an expression is validly annotated
typeCheck :: Expr -> Maybe Tag
typeCheck IntLit{} = Just IntTag
...
typeCheck (ListLit tag els)
  | all good els = Just (ListTag tag)
  | otherwise = Nothing
  where
    good el = case typeCheck el of
                Nothing -> False
                Just res = res == tag