以下代码(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))
它有效,但只有我给出了所有明确的类型签名。有没有其他方法可以做到这仍然允许类型推断?
答案 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
比类型注释更漂亮,可以作为参数等传递。