Haskell:引用更新函数中以前更新的列表元素 [英] Haskell : reference to previously updated elements of list within the update function

查看:103
本文介绍了Haskell:引用更新函数中以前更新的列表元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下定义:

pre $ data Book = Book {id :: Int,title :: String}
type Shelf = [Book]

假设我有一个假设的函数(upd用于更新)

  updShelf :: Shelf  - >书架
updShelf all @(book:books)= updBook book:updShelf books

所有罚款至今。现在我们假设updateBook函数需要在它之前引用 更新的 三本书,也就是说,书架中位置5的book的updateBook需要参考位置2的book(假设前三本书不需要这样的参考来更新)。没问题,我说,并修改我的代码:

  updShelf :: Shelf  - >书架
updShelf所有@(书:书)prevBook = updBook书prevBook:updShelf书
其中prevBook = ???

我需要帮助的是prevBook函数。虽然我甚至不确定我是否以正确的方式处理这个问题。所以,如果你们有更好的建议来解决这个问题,我们将非常感激。



编辑:



< Thomas M. DuBuisson:您的解决方案不适用于我。这是为什么:
假设初始货架(全部)状态为

  Book {id = 1,title =a } 
Book {id = 2,title =b}
Book {id = 3,title =c}
Book {id = 4,title =d}
Book {id = 5,title =e}
Book {id = 6,title =f}
Book {id = 7,title =g} $ b $ (book){b = Book {title =h}

然后(drop 3 partialUpdate)是

  updBook 4 
updBook 5
updBook 6
updBook 7
updBook 8

zipWith'($)(drop 3 partialUpdate)(所有)是:

  updBook 4 1 
updBook 5 2
updBook 6 3
updBook 7 4 - >哎呀!旧版本的书4!
updBook 8 5 - >哎呀!旧版本的书5!

在我的情况中,我需要书籍7和8根据已更新版本的书4进行更新, 5,而不是未更新的。我希望你明白我的意思。

.haskell.org/haskellwiki/Tying_the_Knot>绑结:我们将在计算答案时使用答案。出于说明的目的,我将使用 type Book = Int 来替代。

  updateShelf :: Shelf  - >货架
updateShelf shelf = answer其中
answer = zipWith updateBook移动货架
移动=复制3 Nothing ++ map只需回答

- 一些愚蠢的实现只是为了说明
updateBook ::可能预订 - >书 - > Book
updateBook Nothing current = current + 1
updateBook(Just threeBack)current = current + threeBack + 1

现在,在 ghci 中,我们可以验证 updateShelf 确实在使用更新的版本:

  *主要> updateShelf [1,10,100,1000,10000] 
[2,11,101,1003,10012]



<正如你所看到的,前三个是 1 + 1 10 + 1 100 + 1 ,其余两个是 1000+(1 + 1)+1 10000+( 10 + 1)+1 ,因此正如你所希望的那样使用更新的以前的值。


Say I have the following definitions

data Book = Book {id :: Int, title :: String}
type Shelf = [Book]

Assuming I have a hypothetical function (upd is for update)

updShelf :: Shelf -> Shelf
updShelf all@(book : books) = updBook book : updShelf books

All fine so far. Now let's say the updateBook function needs to refer to the updated book three books before it i.e updateBook for book at position 5 in bookshelf need to refer to book at position 2 (assume first three books need no such reference to update). No problem, I say, and modify my code as such:

updShelf :: Shelf -> Shelf
updShelf all@(book : books) prevBook = updBook book prevBook : updShelf books
                where prevBook = ???

What I need help is with is the prevBook function. Although I am not even sure if I am approaching this problem the right way. So, if you guys have any better suggestion to approach this problem differently, it would be highly appreciated

EDIT:

Thomas M. DuBuisson: Your solution won't work for me. Here's why: Assume initial shelf (all) state as

Book {id=1, title="a"}
Book {id=2, title="b"}
Book {id=3, title="c"}
Book {id=4, title="d"}
Book {id=5, title="e"}
Book {id=6, title="f"}
Book {id=7, title="g"}
Book {id=8, title="h"}

then (drop 3 partialUpdate) is (using only ids rather than entire book statement):

updBook 4
updBook 5
updBook 6
updBook 7
updBook 8

zipWith' ($) (drop 3 partialUpdate) (all) is :

updBook 4 1
updBook 5 2
updBook 6 3
updBook 7 4 -> YIKES! Older version of book 4!
updBook 8 5 -> YIKES! Older version of book 5!

In my case, I need books 7 and 8 to be updated against already updated versions of book 4 and 5,not the un-updated ones. I hope you understand what I mean to convey.

解决方案

This trick is related to tying the knot: we'll use the answer while computing the answer. For the purposes of illustration, I'll use type Book = Int instead.

updateShelf :: Shelf -> Shelf
updateShelf shelf = answer where
   answer  = zipWith updateBook shifted shelf
   shifted = replicate 3 Nothing ++ map Just answer

-- some stupid implementation just for illustration
updateBook :: Maybe Book -> Book -> Book
updateBook Nothing          current = current + 1
updateBook (Just threeBack) current = current + threeBack + 1

Now, in ghci, we can verify that updateShelf is really using the updated versions:

*Main> updateShelf [1,10,100,1000,10000]
[2,11,101,1003,10012]

As you can see, the first three are 1+1, 10+1, and 100+1, and the remaining two are 1000+(1+1)+1 and 10000+(10+1)+1, and are therefore using the updated previous values, just as you'd hope.

这篇关于Haskell:引用更新函数中以前更新的列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆