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'
如果我的mapM
和sequence'
的实现是正确的,并且,因为每个Monad都是一个适用者:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
然后我不清楚为什么mapM
和sequence'
是必要的。他们为什么?
P.S。 - 感谢haoformayor帮助我sequenceA
。
答案 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, MRP(email-thread)正在进行中
Monad
&#39; Monad
和>>
&#39; s Applicative
相同。哪个事件可以说明*>
和traverse = mapM
。但这是一个漫长的过程,需要时间。
所以回答你的问题:出于历史原因。