生成无限列表的顺序成员

时间:2010-12-16 10:36:51

标签: haskell sequence

我生成了无限的实体列表:

entities =
  let f x = x ++ "'" 
  in "x" : "y" : "z" : map f entities

我想定义一个函数,它在每个invokation上返回一个新实体。像这样:

> nextEntity
x
> nextEntity
y
.
.
.

我想这是州立大学的地方,但对指针感激不尽。

一些背景知识:如果您尝试在FOL中表示自然语言句子,则需要为实体指定变量。 “John loves Mary”需要两个变量(一个用于John,一个用于Mary),“John给Mary一本书”需要三个变量(John,Mary,书)等等。处理句子时遇到的每个“事物”的变量名。

所以我想要使用的函数必须跟踪已生成的函数,并在调用时返回下一个函数。

3 个答案:

答案 0 :(得分:5)

  

我想定义一个函数,它在每个invokation上返回一个新实体。像这样:

由于Haskell是一种纯函数式编程语言,根据定义,这是不可能的。任何Haskell函数都将为相同的参数返回相同的值。因此,没有参数的函数是常数。

  

我想这是州立大学的地方,

是的,的确如此。状态monad表示一个可以改变的隐藏状态的计算。使用do构造,您可以将有状态计算组合到共享公共状态的较大计算。特别是,每个计算只是将新状态传递给连续的状态。

虽然用法很简单。

nextEntity :: State [a] a
nextEntity = do 
  entity:rest <- get
  put rest
  return entity

test = do
   e1 <- nextEntity
   e2 <- nextEntity
   e3 <- nextEntity
   return [e1, e2, e3]

res = fst $ runState test entities

答案 1 :(得分:4)

对于一个函数来说,它必须具有某种状态,它在调用时会发生变化,而纯粹的Haskell函数却无法做到这一点。你可以使用State monad,但我认为有更好的方法可以解决你的问题。

以下是国家monad中人们如何做到这一点

nextEntity :: State Int String
nextEntity = do
               s <- get
               put (s+1)
               return (entities !! s)

你可以在状态monad中的计算中使用它,如下所示:

someCalculation = do
                    s1 <- nextEntity
                    s2 <- nextEntity
                    (do something with them)

所以不同的值会被绑定到s1和s2。但所有这一切都应该被视为对州议员的一种练习,因为我相信你有更好的解决办法。

答案 2 :(得分:1)

是的,Monad州就是你想要的。缺点可以这样写:

nextEntity :: State [a] a
nextEntity = modify tail >> gets head

我们可以编写一个函数,为您提供前100个这样的元素:

test = sequence (replicate 100 nextEntity)

像这样打印:

main = sequence_ . map print . evalState test $ entities