结合`$`和`.`运算符

时间:2014-02-16 14:52:57

标签: haskell

以下代码(ideone)尝试创建一个基本上都是.$运算符的运算符,具体取决于它是应用于函数还是值。

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}

class SuperDot a b where
  type Result a b 
  ($.) :: a -> b -> Result a b

instance SuperDot (a -> b) a where
  type Result (a -> b) a = b
  ($.) f x = f x

instance SuperDot (b -> c) (a -> b) where
  type Result (b -> c) (a -> b) = (a -> c)
  ($.) f g = f . g

h1 :: Int -> Int
h1 x = x * 2

h2 :: Int -> Int
h2 x = x + 3

main = print (h2 $. h1 $. (5 :: Int))

它有效,但只有我给出了所有明确的类型签名。有没有其他方法可以做到这仍然允许类型推断?

1 个答案:

答案 0 :(得分:4)

不,因为数字文字真的是Num a => a,你必须提供一些明确的提示,你实际上希望它是Int

然而,我们可以从class-prelude窃取更好的方法。我们可以提供一系列带限制类型的身份函数

 asInt :: Int -> Int
 asInt = id

 asInteger :: Integer -> Integer
 asInteger = id

 asIntFun :: (Int -> a) -> Int -> a
 asIntFun = id

等等然后再写

 main = print (h2 $. h1 $. asInt 5)
 main = asIntFun print $. h2 $. h1 $. asInt 5

比类型注释更漂亮,可以作为参数等传递。