Números como funções multiplicativas (estranhas mas divertidas)
Nos comentários da perguntaComposição da função tácita em Haskell, as pessoas mencionaram fazer umaNum
exemplo paraa -> r
, então eu pensei em brincar usando a notação de função para representar multiplicação:
{-# LANGUAGE TypeFamilies #-}
import Control.Applicative
instance Show (a->r) where -- not needed in recent GHC versions
show f = " a function "
instance Eq (a->r) where -- not needed in recent GHC versions
f == g = error "sorry, Haskell, I lied, I can't really compare functions for equality"
instance (Num r,a~r) => Num (a -> r) where
(+) = liftA2 (+)
(-) = liftA2 (-)
(*) = liftA2 (*)
abs = liftA abs
negate = liftA negate
signum = liftA signum
fromInteger a = (fromInteger a *)
Note que a definição fromInteger significa que eu posso escrever3 4
que avalia a 12, e7 (2+8)
é 70, assim como você esperaria.
Então tudo vai maravilhosamente, divertido esquisito! Por favor, explique este wierdness se você pode:
*Main> 1 2 3
18
*Main> 1 2 4
32
*Main> 1 2 5
50
*Main> 2 2 3
36
*Main> 2 2 4
64
*Main> 2 2 5
100
*Main> (2 3) (5 2)
600
[Edit: usei o Applicative ao invés do Monad porque o Applicative é ótimo em geral, mas não faz muita diferença no código.]