我生成了无限的实体列表:
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,书)等等。处理句子时遇到的每个“事物”的变量名。
所以我想要使用的函数必须跟踪已生成的函数,并在调用时返回下一个函数。
答案 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