Cとモナド

Go言語でEitherモナドは無理がありすぎる感じがした。では、他の言語ではどうだろうか?
C言語では関数の戻り値でエラーかどうかを判定しなければならないことが多いけど、&&演算子の短絡評価を使えば、このように簡潔に書くことも可能だ。

#include <errno.h>
#include <error.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv)
{
  FILE *fp;
  char s[100];

  int ok = (fp = fopen("hello.txt", "r"), fp != NULL)
    && (fscanf(fp, "%99s", s) >= 0)
    && (fclose(fp) >= 0)
    && (printf("%s\n", s) >= 0);
  if (!ok) {
    error(1, errno, "main");
  }
  return 0;
}

実行結果:

c$ gcc -o err err.c
c$ ./err 
./err: main: No such file or directory
c$ echo hello > hello.txt
c$ ./err 
hello
c$ echo > hello.txt
c$ ./err 
./err: main
c$ 

bool値の短絡評価による受け渡し+副作用による環境の書きかえで、Eitherモナド相当のことができるわけだ。Go言語の例とは違って、&&演算子の機能に頼っているこの方法では結局MaybeモナドかEitherモナド相当の機能を実現するためにしか使えないのだけれども、&&や||の短絡評価や、コンマ演算子があるとうれしい理由が少し見える。