I've learned. I'll share.

January 9, 2008

Monads in Ruby (with nice syntax!)

My last article was about how you can do monads in python with nice syntax. Now I'd like to present nice monad syntax in Ruby. I'm not explaining what monads are or how you can use them. For now, I'm expecting you to be familiar with monads. If you aren't, go read a nice article on them.

Imagine you have a Monad base class like this:

class Monad
  def bind(func)
    raise "not implemented"
  end

  def self.unit(val)
    raise "not implemented"
  end

  # bind to block
  def bindb(&func)
    bind(func)
  end
end

As an aside, Please excuse there being a "bind" and a "bindb". It's silly that Ruby differentiates between a block and Proc like that. I also think it's silly that I have to keep typing "lambda {|val| func(val)}" to turn a method into a Proc and "proc.call(val)" to call a Proc. In python, methods, functions, and lambdas are all the same thing, and it's a lot easier to code with. In this sense, python is way better. But Ruby has really slick syntax for passing in the block, and python's lambda restrictions are annoying. Why can't we have the best of both? I guess then I'd need Scala or Perl6. End aside.

Let's implement the Either monad, which I call it Failable:

class Failable < Monad
  def initialize(value, success)
    @value   = value
    @success = success
  end

  def bind(bindee)
    if @success
      bindee.call(@value)
    else
      self
    end
  end

  def self.unit(val)
    self.new(val, true)
  end

  def to_s
    if @success
      "Success(#{@value})"
    else
      "Failure(#{@value})"
    end
  end
end

def success(val)
  Failable.new(val, true)
end

def failure(val)
  Failable.new(val, false)
end

Now we can write some code that safely handles divide by zero without using exceptions (actually, exceptions essentiatlly are the Either monad, but never mind that for now):

def fdiv(a, b)
  if b == 0
    failure("cannot divide by zero")
  else
    success(a / b)
  end
end

def fdiv_with_binding(first_divisor)
  fdiv(2.0, first_divisor).bindb do |val1|
    fdiv(3.0, 1.0)        .bindb do |val2|
      fdiv(val1, val2)    .bindb do |val3|
        success(val3)
      end
    end
  end
end

puts fdiv_with_binding(1.0)
puts fdiv_with_binding(0.0)

Which prints:

Success(0.666666666666667)
Failure(cannot divide by zero)

But it's not very pretty. Luckily, ruby has callcc, which makes it very easy to define a function which I'll call "rbind" which can do this:

def fdiv_with_rbinding(first_divisor)
  with_monad Failable do
    val1 = rbind fdiv(2.0, first_divisor)
    val2 = rbind fdiv(3.0, 1.0)
    val3 = rbind fdiv(val1, val2)
    val3
  end
end

def with_monad(monad_class, & block)
  begin
    val = block.call()
    if val.class == monad_class
      val
    else
      monad_class.unit(val)
    end
  rescue MonadEscape => escape
    escape.monad
  end
end

def rbind(monad)
  begin
    checked_callcc {|cc| monad.bind(cc)}
  rescue ContinuationUnused => unused
    raise MonadEscape.new(unused.result)
  end
end

class MonadEscape < RuntimeError
  attr :monad

  def initialize(monad)
    @monad = monad
  end
end

def checked_callcc(&with_cc)
  callcc do |cont|
    val = with_cc.call(lambda {|val| cont.call(val)})
    raise ContinuationUnused.new(val) if cont
    val
  end
end

class ContinuationUnused < RuntimeError
  attr :result
  
  def initialize(result)
    @result = result
  end
end  

Ruby's block syntax makes it very nice to say "with_monad Monad do", which I like. But I don't really like seeing "= rbind". I'd really like it if we could override "<<" and read that as "=<<", but I think we're stuck with unary operators ("+", "-", "~", all of which look bad here) or words. At least we can choose our name, unlike in python where we have to use "yield". Does anyone have any idea for a better name?

Maybe "xx" would work:

def fdiv_with_rbinding(first_divisor)
  with_monad Failable do
    val1 =xx fdiv(2.0, first_divisor)
    val2 =xx fdiv(3.0, 1.0)
    val3 =xx fdiv(val1, val2)
    val3
  end
end

So there you have it. You can have nice monad syntax in Ruby using callcc. Unfortunately, I've read that not all implementations of Ruby have continuatoins, which means JRuby and IronRuby may be left out in the cold. Keep in mind that Ruby's "yield" syntax is NOT a true generator, which means that we can't use the same trick that we used in python. It's callcc or nothing.

Here's the complete code in case you want to cut and paste it:

############# Monad Base ##############

class Monad
  def bind(func)
    raise "not implemented"
  end
  
  def self.unit(val)
    raise "not implemented"
  end

  # bind to block
  def bindb(&func)
    bind(func)
  end
end

def with_monad(monad_class, &block)
  begin
    val = block.call()
    if val.class == monad_class
      val
    else
      monad_class.unit(val)
    end
  rescue MonadEscape => escape
    escape.monad
  end
end

# "reverse" bind, or bind to the return value, or bind to the continuation
def rbind(monad)
  begin
    mycallcc {|cc| monad.bind(cc)}
  rescue ContinuationUnused => unused
    raise MonadEscape.new(unused.result)
  end
end


class MonadEscape < RuntimeError
  attr :monad

  def initialize(monad)
    @monad = monad
  end
end

def mycallcc(&with_cc)
  used = false
  val  = callcc do |cc|
    fake_cc = lambda do |val| 
      used = true
      cc.call(val)
    end

    with_cc.call(fake_cc)
  end

  raise ContinuationUnused.new(val) unless used
  val
end 

class ContinuationUnused < RuntimeError
  attr :result
  
  def initialize(result)
    @result = result
  end
end  

############# Failable Monad ##################

class Failable < Monad
  def initialize(value, success)
    @value   = value
    @success = success
  end
      
  def bind(bindee)
    if @success
      bindee.call(@value)
    else
      self
    end
  end

  def self.unit(val)
      self.new(val, true)
  end

  def to_s
    if @success
        "Success(#{@value})"
    else
        "Failure(#{@value})"
    end
  end
end

def success(val)
  Failable.new(val, true)
end

def failure(val)
  Failable.new(val, false)
end

######## Failable Monad Example ##########

def fdiv(a, b)
  if b == 0
    failure("cannot divide by zero")
  else
    success(a / b)
  end
end

def with_failable_binding(first_divisor)
  fdiv(2.0, first_divisor).bindb { |val1|
    fdiv(3.0, 1.0)        .bindb { |val2|
      fdiv(val1, val2)    .bindb { |val3|
        success(val3)
      }
    }
  }
end

def xx(monad)
  rbind(monad)
end

def with_failable_rbinding(first_divisor)
  with_monad Failable do
    val1 =xx fdiv(2.0, first_divisor)
    val2 =xx fdiv(3.0, 1.0)
    val3 =xx fdiv(val1, val2)
    val3
  end
end

puts with_failable_binding(1.0)
puts with_failable_binding(0.0)
puts with_failable_rbinding(1.0)
puts with_failable_rbinding(0.0)

75 comments:

  1. I think what I have the biggest problem is... what to do with this?

    ReplyDelete
  2. I plan to write another article (or maybe a few) explaining what you can do with monads, and thus this syntax. Explaining how this works was big enough for one article (actually, two, there was one for python as well).

    ReplyDelete
  3. I don't have a haskell background so I've no idea what monads might be useful for, but here's how to get around your bind/bindb thing.

    def bind( proc = nil, &block )
    actual_bind( proc || block )
    end

    ReplyDelete
  4. Peter: combinator parsing!

    ReplyDelete
  5. afaik there is a difference between blocks and functions. the difference has to do with scope. sry i have no link available.

    ReplyDelete
  6. Maybe the Superator gem would enable you to use <- as an operator instead of =xx?

    ReplyDelete
  7. Methods may override operators: .., |, ^, &, <=>, ==, ===, =~, >, >=, <, <=, +, -, *, /, %, **, <<, >>, ~, +@, -@, [], []= (2 args)

    ReplyDelete
  8. It wouldn't have to be Scala or Perl6: see The Lord of the Lambdas to find out the alternative.

    ReplyDelete
  9. Hi Peter!
    This is another great bit of code (after your "Pysec" parser) - very nice!

    You very kindly agreed that Pysec could be used as public domain when I asked about it (in comments at bottom of that page - I'm the Andy there), so may I also include this Ruby parser in the public-domain collection of code that I'm putting together? (You will be credited and praised, that goes without saying...) Very many thanks for your time - bye for now!
    - Andy
    ( Oh, and btw, is it possible for you to email your email address to me? That is so I can email you to ask/thank you in future, instead of doing so via comments... Mine is - andy dot elvey at paradise dot net dot nz ) Thanks!
    - Andy

    ReplyDelete
  10. Hi Peter,

    There is now a ruby gem, Rumonade, that implements these ideas:
    https://github.com/ms-ati/rumonade

    If you give it a try, please let me know what you think of it in terms of correctness and (more importantly) usability.

    In terms of implementation, in Rumonade the Monad mix-in requires that the host class implement self.unit and #bind, and it adds the rest. Array is adapted for it, and it adds an Option and Either class so far.

    ReplyDelete
  11. There is also the monadic gem https://github.com/pzol/monadic which implements the monads with inheritance.

    ReplyDelete
  12. Bạn đang cần tìm địa chỉ mua hàng Trung Quốc tốt nhất? Hãy đến với lamphongchina. Chúng tôi là nơi chuyên cung cấp các Dịch vụ vận chuyển hàng hóa từ trung quốc uy tín chất lượng, Dịch vụ đặt mua hàng từ Trung Quốc, vận chuyển hàng hóa từ quảng châu về việt nam... Khi bạn đến với chúng tôi, chúng tôi sẽ giải đáp các thắc mắc cho bạn. Khi bạn gặp rắc rối chúng tôi sẽ hổ trợ bạn giải quyết vấn đề. Đối với những cần nhập hàng Trung Quốc giá rẻ thì chúng tôi đã có Dịch vụ nhập hàng từ Trung Quốc về Việt Nam giá rẻ sẽ giúp bạn giải quyết. Hãy đến với chúng tôi để được phục vụ tốt nhất nhé.

    ReplyDelete
  13. تعتبر العاب تلبيس من اشهر الانواع في هذا المجال وهي بدورها تتضمن عدة اصناف جميلة ويعشقها الكتير وخاصة البنات منها العاب تلبيس ومكياج التي تمزج بين التلبيس وكذلك الميك اب في آن واحد هذا الامر الدي يزيد من جمالها وتجعل كل من يلعبها يستمتع بذلك زد على ذلك العاب تلبيس باربي التي تعرف شعبية كبيرة لانها شخصية مشهورة ويعرفها الصغير والكبير ولهم ذكريات جميلة معها لانها اشتهرت في عالم الكارتون والان اصبح الامر كذلك في مجال الالعاب وغير هذا هناك كذلك نوع آخر مميز ايضا وهو العاب تلبيس عرائس فالجميع يحلم ان يقوم بتلبيسهما لانها تذكرهم بهذه المناسبة الجميلة الا وهي الزواج التي تعتبر اهم مرحلة في حياة الانسان وهناك انواع مغايرة لها جمهور كبير في كل انحاء العالم وهي العاب قص الشعر ليس هي فقط بل توجد ايضا العاب طبخ التي يمكن للجميع لعبها سواء كانوا اولادا او بناتا وهي الاكتر طلبا في النت ويحبها الجميع ومعها ايضا العاب باربي التي تكلمنا عليها بكل انواعها تتنوع العاب فلاش وذلك على حسب كل شخص ورغبته فهناك عدة انواع منها وهناك من هي خاصة بالبنات واخرى للاولاد وتعتبر العاب تلبيس من اكتر الالعاب انتشارا في الويب وهي محبوبة عند الجميع ولديها جمهور واسع كما انها سهلة اللعب والجميع يمكنه لعبها بسهولة تامة بدون صعوبات تذكر كما ان هناك انواع اخرى متل العاب طبخ والعاب اكشن ومكياج و سيارات الى غير ذلك فلك صنف جمهوره ومحبيه ولكن تبقى العاب بنات الاكتر انتشارا وشعبيتنا في عالم العاب الفلاش كما انها تحتوي على شخصيات معروفة وغنية عن التعريف متل باربي و سندريلا وشخصيات اخرى تركت بصمتها في هذا المجال لهذا اصبح يعتمد عليها كتيرا في صنف العاب تلبيس بنات الدي تحبه البنات بكترة خاصة في العالم العربي مما يجعل المواقع الخاصة بهذا النوع تزداد يوما بعد الاخر فذلك ليس عبثا ففي الحقيقة نوع العاب التلبيس من اجمل اصناف العاب فلاش بصفة عامة و العاب بنات بصفة خاصة

    ReplyDelete
  14. Many parents think that the job of ensuring their children get the best education possible and go the furthest possible is entirely up to the schools, but this really isn't the case. Parents are the most influential force in the educational future of their children. As parents think and dream about where their kids will go with their education, many envision their child being the first in the family to graduate college.http://www.how-todo.xyz/

    ReplyDelete
  15. Here you can find some additional info about assignment writing

    ReplyDelete
  16. I am currently studying programming, but this is somehow too difficult for me and I order some of my works on an essays service, because I do not have time to do everything in time. On the one hand, I am glad that there are services that provide professional assistance, but on the other, I doubt that I chose the future profession properly.

    ReplyDelete
  17. We will discuss Ruby which is an object-oriented language with classes and methods. Classes are introduced with the keyword class and methods with the keywords. According to the experts, it is very useful to us. Cheap dissertation writing service.

    ReplyDelete
  18. What is a network engineer? This is someone who you may also hear referred to as a computer network architect. Network engineer requirements include essential skills in the design, planning, implementation and monitoring a computer network that supports wireless network services, video, data, and voice. This is a high-level profession. There are a lot of different types of networks that someone in this role can work with. Some examples include VoIP, which is Voice Over Internet Protocol Network, DAN - Desk Area Network, PEN - Personal Area Network, WLAN, which is Wireless Local Area Network, and LAN, which is Local Area Network.

    ReplyDelete
  19. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. Are you not able to fix the problem with the Canon Printer? Just follow the steps which are mention on the blog to Resolve Canon printer error Code 5100 issue. Thanks!

    ReplyDelete
  20. Let's now learn the important reasons due to which Python language is used at a wider range of people. best course to learn web development with python

    ReplyDelete
  21. If you want to wish international clients or friends a Happy New Year use one of the most common Happy New Year quotes in different languages. Happy New Year Wishes

    ReplyDelete
  22. Thankful to you for sharing this key information! Need you will stick doing such an activities you're doing. Website: Hp 79 Service Error

    ReplyDelete
  23. Visit to create your Webrootaccount. Install Webroot on your device from webroot.com/safe to remove viruses and bugs
    webroot.com/safe

    ReplyDelete
  24. McAfee software has several features like protection against viruses and malware, permanently delete the damaged data, protection for many devices, etc.
    Mcafee.com/activate



    Microsoft Office is client software available for data collection
    Office.com/setup

    ReplyDelete
  25. Compare Coursework writing services to draw every person’s interest, Establish and clarify the exact arrangement or possessions of all homework. Insert articles linked to people. Grab the difficulties that come up in just how chosen subject. Illustrate how issues may be at the homework and offer a remedy to overcome all those issues. Find connections between those writers. Asses sing your own idea. All Assignment Help composing writing can possibly be an effective means to generate a fantastic mission.

    ReplyDelete
  26. You can also make online flower delivery Pune with the help of Gifola's mobile application. Our mobile app makes the whole process of buying and sending flowers to Pune much easier and on-the-go. The same delivery options can be selected by you while making flower delivery using our mobile application. Ensure to choose the correct date, time, and slot so that we can serve you and your loved ones in Pune with the best of our delivery services. Another noteworthy point that makes us stand out from our competitors is the fact that every flower arrangement chosen by you for your relationships is hand-delivered by our delivery team with the same warmth and affection that you would have done personally.

    Send Flowers to Pune

    ReplyDelete
  27. Order cakes and flowers Online in gurgaon by Gifola . Send unique combo of cakes and flowers to gurgaon for all special occasions to your loved ones. ✓Free Home Delivery ✓Same Day Delivery

    online cakes and flowers gurgaon

    ReplyDelete
  28. Are you searching for online Certified Medical Document Translation Services? If yes, then you are at the right place. Our certified translators provide an exact translation of medical documents like Medical Device Manuals, Hospital Documents, Medical Reports, Medical Manual, Autopsy Reports, and many others. Global Translation Help guarantees that you can receive only high-quality medical record translation at a reasonable price. For instant translation help, please connect with our experts now.

    ReplyDelete
  29. If you are searching like help in UK with online exam help
    then you can get at studentsassignmethelp.co.uk. It has over 2000 expert writers who are the best in their field and have received a high number of positive feedback from UK students. If you employ a writer from SAH, you can contact them at any time via phone, email, or live chat. They are available 24 hours a day, 7 days a week to assist you. They often academic writing like thesis writing help like online exam help,research paper writing,essay writing, online exam help,thesis writing,homework,research paper writing,case study,essay,thesis writing ,addition to online exam help with 100% plagiarism free at a very low cost.

    ReplyDelete
  30. Singaporetranslators.com is being one of the most active translation help websites in Singapore which has a great pool of over 500+ translators who offer Malaysia birth certificate translation in short turn around .Our experts have translated thousands of documents to the local and international clients at very reasonable price.

    ReplyDelete
  31. Thank you for posting such a great article! I found your website perfect for my needs. It contains wonderful and helpful posts. Keep up the good work!. Thank you for this wonderful Article! 메이저사이트

    ReplyDelete
  32. Thanks for sharing this awesome content, it would be helpful
    Guys just sharing, I’ve found this interesting! Check it out! 경마사이트

    ReplyDelete
  33. May I simply just say what a relief to discover someone that actually knows what they are talking about online. You actually know how to bring an issue to light and make it important. 카지노사이트

    ReplyDelete
  34. A lot more people ought to look at this and understand this side of the story. It’s surprising you aren’t more popular given that you definitely possess the gift. 사설토토

    ReplyDelete
  35. Thanks for sharing this informative content.,
    Leanpitch provides online training in Scrum Master Certification during this lockdown period everyone can use it wisely.
    Join Leanpitch 2 Days CSM Certification Workshop in different cities.

    Scrum master certification online

    CSM certification online

    CSM online

    CSM online certification

    CSM online training

    CSM training online

    Scrum master training online

    ReplyDelete
  36. I think youve created some actually interesting points. Not also many people would actually think about this the way you just did.

    스포츠토토
    바카라사이트
    파워볼 메이저사이트
    카지노사이트

    ReplyDelete
  37. This domain seems to receive a great deal of visitors. How do you advertise it? It offers a nice individual spin on things.

    토토
    스포츠토토
    토토사이트
    먹튀검증

    ReplyDelete
  38. Im still learning from you, but Im making my way to the top as well. I definitely love reading everything that is posted on your site.

    사설토토
    온라인카지노
    파워볼게임
    온라인바카라

    ReplyDelete
  39. I have been reading out many of your articles and it’s clever stuff. I will make sure to bookmark your blog. 경마사이트

    ReplyDelete
  40. But wanna comment on few general things, The website pattern is perfect, the content material is really fantastic 온라인카지노

    ReplyDelete
  41. I went over this internet site and I think you have a lot of great info , saved to favorites. 토토

    ReplyDelete
  42. It was a wonderful chance to visit this kind of site and I am happy to know. thank you so much for giving us a chance to have this opportunity
    야설
    Feel free to visit my blog :
    야설

    ReplyDelete
  43. Nice to be visiting your blog again. it has been months for me. Well this article that i’ve been waited for so long. I need this article to complete my assignment in the college. and it has same topic with your article. Thanks. great share
    일본야동
    Feel free to visit my blog :일본야동

    ReplyDelete
  44. Hello, I think that I saw you visited my weblog so I came to “return the favor". I'm attempting to find things to enhance my website! I suppose its ok to use a few of your ideas!!
    국산야동
    Feel free to visit my blog : 국산야동

    ReplyDelete
  45. Ahaa, its good discussion about this post here at this webpage, I have read all that, so at this time me also commenting 일본야동
    Feel free to visit my blog : 일본야동

    ReplyDelete
  46. I don't know who you are but certainly you are going to a famous blogger if you aren't already ;) Cheers! 야설
    Feel free to visit my blog : 야설

    ReplyDelete
  47. Thanks Your post is so cool and this is an extraordinary moving article and If it's not too much trouble share more like that.
    Digital Marketing Course in Hyderabad

    ReplyDelete
  48. Hi everyone, it’s my first go to see at this web page, and paragraph


    토토사이트
    토토
    안전놀이터

    ReplyDelete
  49. I was impressed by the good writing.Thank you.
    If you want to know the social graph game, come here!

    Great article, totally what I was looking for.


    스포츠토토
    토토사이트
    먹튀검증

    ReplyDelete
  50. Yay google is my queen assisted me to find this great web site!


    바카라사이트
    온라인카지노
    카지노

    ReplyDelete
  51. If some one wants expert view on the topic of blogging
    and site-building then i recommend him/her to go to see this web site,
    Keep up the good work.


    카지노사이트
    바카라사이트
    홈카지노


    ReplyDelete
  52. You have done excellent job Thanks a lot and I enjoyed your blog. Great Post.
    Data Science Certification in Hyderabad

    ReplyDelete
  53. Great post happy to see this. I thought this was a pretty interesting read when it comes to this topic Information. Thanks..
    Artificial Intelligence Course

    ReplyDelete
  54. Nice Post thank you very much for sharing such a useful information and will definitely saved and revisit your site and i have bookmarked to check out new things frm your post.
    Data Science Course

    ReplyDelete
  55. Your website is really cool with great inspiring articles and thanks for sharing this amazing and educative blog post!
    Cloud Computing Courses in Hyderabad

    ReplyDelete
  56. Thank you for sharing this wonderful blog, I read that Post and got it fine and informative. Please share more like that...
    Ethical Hacking Institute in Bangalore

    ReplyDelete
  57. Excellent read, I just passed this onto a friend who was doing a little research on that. And he actually bought me lunch as I found it for him smile Therefore let me rephrase that: Thank you for lunch. 토토사이트


    ReplyDelete
  58. Hi There! How you have been doing? Did you understand everything expressed in the above write-up? Well certainly, I have and I want to praise the author because I can see talent here. The author has explained everything from scratch without going into too many details and that is a very hard skill to master. I am a digital content writer as well, and I have experience working in pre-eminent companies such as Webroot and Norton. But I still make mistakes, and I like criticism because it helps me improve my work. So, go to the following link and help me become a better version of myself:

    ij.start.canon
    ij.start.canon
    canon.com/ijsetup

    ReplyDelete
  59. I was browsing the internet for information and found your blog. I am impressed with the information you have on this blog.
    Data Science Course Fees

    ReplyDelete
  60. I don't know if it's just me or if everybody else encountering problems
    with your website. It appears like some of the text in your
    posts are running off the screen. Can someone else please comment and let me know
    if this is happening to them As well? This could be a problem with my browser because I've had this happen before.

    Appreciate it 토토사이트

    ReplyDelete
  61. I was browsing the internet for information and found your blog. I am impressed with the information you have on this blog
    Data Science Course Fees

    ReplyDelete
  62. Excellent post to make this blog more wonderful, attractive and cool stuff you have. Thank You.
    Data Science Course in India with Placements

    ReplyDelete

Blog Archive

Google Analytics