可穿越的#mapM&序列 - 必要吗?

时间:2015-12-28 03:37:46

标签: haskell

Typeclassopedia呈现Traversable:

class (Functor t, Foldable t) => Traversable t where
  traverse  :: Applicative f => (a -> f b) -> t a -> f (t b)
  sequenceA :: Applicative f => t (f a) -> f (t a)
  mapM      ::       Monad m => (a -> m b) -> t a -> m (t b)
  sequence  ::       Monad m => t (m a) -> m (t a)
  

一个好的练习是弄清楚默认的实现应该是什么:给定traverse或sequenceA,你将如何定义其他三种方法?

我想出了以下代码检查代码:

class (Functor t, Foldable t) => MyTraversable t where
  traverse'  :: Applicative f => (a -> f b) -> t a -> f (t b)
  traverse' = error "..."
  sequenceA' :: Applicative f => t (f a) -> f (t a)
  sequenceA' f = traverse' id f
  mapM      ::       Monad m => (a -> m b) -> t a -> m (t b)
  mapM = traverse'
  sequence'  ::       Monad m => t (m a) -> m (t a)
  sequence' = sequenceA'

如果我的mapMsequence'的实现是正确的,并且,因为每个Monad都是一个适用者:

λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...

然后我不清楚为什么mapMsequence'是必要的。他们为什么?

P.S。 - 感谢haoformayor帮助我sequenceA

1 个答案:

答案 0 :(得分:5)

正如评论中所述,曾经有一段时间不是每个public class SessionManager : INotifyPropertyChanged { public delegate void NewDayEventHandler(object sender, EventArgs ea); public event NewDayEventHandler NewDayEvent; private Timer _timer; private Stopwatch _clockWatch; private DateTime current_time; #region Properties public DateTime CurrentTime { get { return DateTime.Now; } set { if (current_time != value) { current_time = value; OnPropertyChanged("CurrentTime"); } } } public List<Session> OpenSessions { get; private set; } public ObservableCollection<UIElement> Entries { get; private set; } public Session CurrentSession { get { return current_session; } set { if (current_session != value) { current_session = value; OnPropertyChanged("CurrentSession"); } } } #endregion public SessionManager() { _clockWatch = new Stopwatch(); _timer = new Timer(1000);//one second _timer.Elapsed += timerElapsed; //Code removed for clarity current_time = new DateTime(); CurrentTime = DateTime.Now; _timer.Start(); } #region Methods #region Event Methods /// <summary> /// Registered to Timer.Elapsed Event /// (See constructor) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void timerElapsed(object sender, ElapsedEventArgs e) { CurrentTime = DateTime.Now; if ((CurrentTime.TimeOfDay.Hours == 13 && CurrentTime.TimeOfDay.Minutes == 23 && CurrentTime.TimeOfDay.Seconds == 0) && NewDayEvent != null) { NewDayEvent(this, new EventArgs()); } } #endregion #region Class Methods private void OnPropertyChanged([CallerMemberName] string member_name = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(member_name)); } } #endregion #endregion public void SplitSession() { Session prevSesh = CurrentSession; OpenSessions.Add(new Session()); CurrentSession = OpenSessions.Last(); current_session.addComment( ((TimeEntry)Entries.Last( x => x.GetType() == typeof(TimeEntry)) ).Data.Comment); } } 都是Monad。 就在最近(在GHC 7.10附带的Applicative中)base-4.8成为Applicative的超类。您可能已经看过Applicative-Monad-Proposal, AMP

目前,Monad of no return, MRPemail-thread)正在进行中 Monad&#39; Monad>>&#39; s Applicative相同。哪个事件可以说明*>traverse = mapM。但这是一个漫长的过程,需要时间。

所以回答你的问题:出于历史原因