## Archive for August, 2014

Wednesday, August 13th, 2014

Consider the following function:

```oddness :: Maybe Int oddness = do let a = Just 1 :: Maybe Int b <- a return b```

Perfectly fine, albeit contrived, redundant, etc. Bear with me. Now consider what happens if we change the value of `a`:

```oddness :: Maybe Int oddness = do let a = Nothing :: Maybe Int b <- a return b```

This looks odd, because it looks like we’re extracting the value from `a` into `b`, and then passing it to `return` – it looks like there’s some `Int` we extract from `Nothing`, and calling `return` converts it back to `Nothing`.

But of course, we know that this do-notation desugars to something like:

```oddness :: Maybe Int oddness = let a = Nothing :: Maybe Int in a >>= \b -> return b```

And recall the definition of `(>>=)` for `Maybe`:

```instance Monad Maybe where (Just x) >>= k = k x Nothing >>= _ = Nothing```

So what’s happening here is that what’s on the right of `(>>=)` remains unevaluated, and `Nothing` is the result. Mystery solved.

### C++ Guru Question – followup

Tuesday, August 12th, 2014

(following on from C++ Guru Question)

There are a few reasons why the code before didn’t work: mainly

a) C++ template argument deduction works one-way with a list of candidates, it’s not H-M type inference.
b) A C++ lambda is a thing with some internal type, not a std::function (although it can be assigned to one, that doesn’t matter for template type deduction).

Anyway, a reasonable solution to this problem is to simplify the template argument matching to the function type, and use a simple function_traits template to take apart the function argument and return types.

```template <typename T> struct function_traits : public function_traits<decltype(&T::operator())> {};   template <typename R, typename A> struct function_traits<R(A)> { typedef R returnType; typedef A argType; };   template <typename C, typename R, typename A> struct function_traits<R(C::*)(A) const> : public function_traits<R(A)> {};   template <typename T> struct Foo { T m_t; };   template <typename F> typename function_traits<F>::returnType operator/=( Foo<typename function_traits<F>::argType> foo, const F& fn) { return fn(foo.m_t); }   void mystery() { auto foo = Foo<int>{1};   // this works... function<Foo<int>(int)> f1 = [] (int i) { return Foo<int>{i}; }; auto bar1 = foo /= f1;   // this does too! auto f2 = [] (int i) { return Foo<int>{i}; }; auto bar2 = foo /= f2; }```

### C++ Guru Question

Monday, August 11th, 2014

Wondering about this… template argument deduction succeeds for the explicitly-typed variable, fails in the auto case. (Also, it succeeds either way for an equivalently-typed unary operator template).

```template <typename T> struct Foo { T m_t; };   template <typename T, typename U> Foo<U> operator/=(Foo<T> foo, function<Foo<U>(T)> fn) { return fn(foo.m_t); }   void mystery() { auto foo = Foo<int>{1};   // this works... function<Foo<int>(int)> f1 = [] (int i) { return Foo<int>{i}; }; auto bar1 = foo /= f1;   // this doesn't auto f2 = [] (int i) { return Foo<int>{i}; }; auto bar2 = foo /= f2;   // clang++ 3.3-16ubuntu1 says: // file:line:col: error: no viable overloaded '/=' // auto bar2 = foo /= f2; // ~~~ ^ ~~   // file:line:col: note: candidate template ignored: could not match // 'function<Foo<type-parameter-0-1> (type-parameter-0-0)>' against // '<lambda at file:line:col>' // Foo<U> operator/=(Foo<T> foo, std::function<Foo<U>(T)> fn) // ^ }```