我读了一些关于monad的帖子和博客,也许,只是,没什么..但是没有真正得到它:/ 在给定的代码中,我必须实现“latestActivity”函数。 在我看来它应该工作,但我不知道如何正确使用“只是”。也许有人能够帮助我。
module LatestActivity where
{-
Write a function 'latestActivity' that finds that last time a specific user
has sent a message. It is given a user name and a list of messages. A message
consists of the time it was sent, the user name of the user who sent it and
the message content. If there is no message from the given user in the list
the function yields 'Nothing'. Otherwise it yields 'Just' the latest time stamp
of the messages of that user in the list.
-}
import Data.List (sort)
-- | A time stamp represented as an 'Integer'
type AbsoluteTime = Integer
-- | A user name represented as a 'String'
type UserName = String
-- | A message consists of the time it was sent, the user who sent it
-- and the actual message content.
data Message = Message {
_timeStamp :: AbsoluteTime,
_userName :: UserName,
_messageContent :: String}
-- | Given a user name and a list of sent messages finds 'Just' the last time
-- a user has sent a message or 'Nothing' if the user has not sent anything.
-- The messages are not assumed to be ordered in any way.
latestActivity :: UserName -> [Message] -> Maybe AbsoluteTime
latestActivity _ [] = Nothing
latestActivity x y =
if (x == (_userName (last y))) -- x equals username in last list element?
then (_timeStamp (last y)) -- print it
else (latestActivity x init y) -- otherwise delete last listelement, recursion till list is empty
答案 0 :(得分:5)
@rightfold提供了一个可能的解决方案,但请注意您的方法不是非常惯用的Haskell。 "否则删除最后一个听众"是程序性思维,而不是你想要推理Haskell函数的方式。无论如何,你的代码中并没有真正发生这种情况,你不能删除Haskell中的东西,但需要在每次迭代时建立一个新的列表:因此,它的效率非常低,因为{{1并且last
需要遍历整个列表才能完成任何其他操作。
基本上,您正在做的是通过列表进行搜索,从前到后。因此,显而易见的首要任务是反转列表,以便您可以随时搜索(并且列表已经过优化)。
init
现在,这可以实现
通过简单的模式匹配递归列表:
latestActivity user = earliestAct . reverse
where earliestAct = ...
或者:正如我所说,这只是一个标准搜索。那么为什么不使用标准find
函数!
earliestAct [] = Nothing
earliestAct (Message t user' txt : msgs)
| user' == user = Just txt
| otherwise = earliestAct msgs
在这里,我已使用 earliestAct = fmap _messageContent . find ((==user) . _userName)
Functor
实例从已找到的邮件中提取内容(如果有的话)。
答案 1 :(得分:2)
只需添加... Just
:v
latestActivity :: UserName -> [Message] -> Maybe AbsoluteTime
latestActivity _ [] = Nothing
latestActivity x y =
if x == _userName (last y)
then Just (_timeStamp (last y))
else latestActivity x (init y)