Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answermy answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

  • Also noticed nextPlayerMove may do IO. In Haskell you would not have a function interleaved with a monad, unless it is a deterministic mathematical function. For example if it used Random numbers or IO you would need a monadic transformer, see StateT here.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

  • Also noticed nextPlayerMove may do IO. In Haskell you would not have a function interleaved with a monad, unless it is a deterministic mathematical function. For example if it used Random numbers or IO you would need a monadic transformer, see StateT here.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

  • Also noticed nextPlayerMove may do IO. In Haskell you would not have a function interleaved with a monad, unless it is a deterministic mathematical function. For example if it used Random numbers or IO you would need a monadic transformer, see StateT here.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

added 338 characters in body; deleted 6 characters in body
Source Link
  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

  • Also noticed nextPlayerMove may do IO. In Haskell you would not have a function interleaved with a monad, unless it is a deterministic mathematical function. For example if it used Random numbers or IO you would need a monadic transformer, see StateT here.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

  • Also noticed nextPlayerMove may do IO. In Haskell you would not have a function interleaved with a monad, unless it is a deterministic mathematical function. For example if it used Random numbers or IO you would need a monadic transformer, see StateT here.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.

Source Link

  • You cannot have something named "X" theoretically does not mean you cannot have anything anyone at sometime thought to be "X". See my answer to another question for a feeling of what you can expect to get in the way of a monad pattern in an object oriented language.

  • What really concerns me is this:

     // liftM :: m t -> (t -> u) -> m u -- looks more similar to bind this way 

    Why is it called lift? Because it takes a function in and gives a function out, but in another domain. (t -> u) -> m t -> m u should be read as (t -> u) -> (m t -> m u), which translates to something like Func<Func<T, U>, Func<M<T>, M<U>>> in C#.

  • You should not overwrite local variables, let alone repetitively, let alone in functional-style aspirant code:

     game = State<Player>.Lift<GameState, GameState>(game, nextPlayerMove); game = State<Player>.Lift<GameState, GameState>(game, drawBoard); game = State<Player>.Bind<GameState, GameState>(game, findWinner); 
  • You don't do Monad and while loop. You should use a foldM.

In adopting functional paradigms, you should start with the low hanging fruits. Avoiding mutable state and preferring expressions over statements, etc. And look for opportunities for reification. Aim for making implicit patterns explicit (for example using applicative alternatives from IEnumerable/IQueryable instead of loops) , composability and as much compile time guarantees as possible.