# Bind-like operator for dogs

**URL:** <https://discourse.haskell.org/t/bind-like-operator-for-dogs/4553>\
**Category:** Learn\
**Created:** [May 18, 2022, 7:41am UTC](https://discourse.haskell.org/t/bind-like-operator-for-dogs/4553 "2022-05-18T07:41:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![niko](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/niko/32/2351_2.png) [@niko](https://discourse.haskell.org/u/niko)\
**Post date:** [May 18, 2022, 7:41am UTC](https://discourse.haskell.org/t/bind-like-operator-for-dogs/4553/1 "2022-05-18T07:41:11Z")

</div>

I’m in search of operators that I can use like `>>=` to keep the chain of operators “flowing” without the need of additional `Just`s (line 17 and 18).

```haskell
module Main where

import Control.Monad (mfilter)

main :: IO ()
main =
  print $
    create "Jim"
      >>= train 1
      >>= train 4
      >>= train 1
      >>= train 4
      >>= train 2
      >>= train 2
      >>= Just . rename "Lilly"
      >>= mfilter (not . isToClever) . Just
      >>= train 4
      >>= train 2

data Dog = Dog String Int deriving (Show)

create :: String -> Maybe Dog
create name =
  if null name
    then Nothing
    else Just $ Dog name 0

train :: Int -> Dog -> Maybe Dog
train hours (Dog name level) =
  let newLevel
        | hours > 6 = Nothing
        | hours == 0 = Just level
        | hours < 3 = Just (level + 2)
        | otherwise = Just $ level + hours
   in Dog name <$> newLevel

rename :: String -> Dog -> Dog
rename newName (Dog _ level) =
  Dog newName level

isToClever :: Dog -> Bool
isToClever (Dog _ level) =
  level > 100

```

so the code looks like this:

```haskell
      >>= train 2
      >>= train 2
      ??? rename "Lilly"
      ??? mfilter (not . isToClever)
      >>= train 4

```

Notes: I tried to find a type on hoogle, but didn’t find one that chains as nice as \>\>=. A simple \<$\> works for the `rename "Lilly"` case, but then the flow is broken.

---

<div class="post-metadata">

**Author:** ![CarstenK](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/carstenk/32/2087_2.png) [@CarstenK](https://discourse.haskell.org/u/CarstenK)\
**Post date:** [May 18, 2022, 8:26am UTC](https://discourse.haskell.org/t/bind-like-operator-for-dogs/4553/2 "2022-05-18T08:26:43Z")

</div>

I’m not sure if it works with operator-precedence but this should be [`<&>`](https://hackage.haskell.org/package/base-4.16.1.0/docs/Data-Functor.html#v:-60--38--62-)

---

<div class="post-metadata">

**Author:** ![wiz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/wiz/32/2408_2.png) [@wiz](https://discourse.haskell.org/u/wiz)\
**Post date:** [May 19, 2022, 11:03am UTC](https://discourse.haskell.org/t/bind-like-operator-for-dogs/4553/3 "2022-05-19T11:03:38Z")

</div>

No need for fancy operators. Just state your intention as it is: `pure . rename`. Or make `rename` into the same shape as the `train`.
