Min*_*sta 3 haskell types nested tuples function
有人在做一个关于将函数应用两次的函数的练习时问我这个问题,我觉得它很有趣.
我们的想法是我们应该使函数两次,它接受一个函数和一个输入,并将函数应用两次,例如
twice :: (a -> a) -> a -> a
twice f x = f ( f x )
Run Code Online (Sandbox Code Playgroud)
打字通常很有意义.不幸的是,对于元组中的元组和函数fst我们可能认为可以使用它,((1,2),3)但由于类型的原因,这是不可能的twice.
有没有办法让这样的东西有效?
由于您的输入f = fst是多态的,并且两个调用隐式涉及不同的类型,因此无法进行输入.如果我们将调用显式化,它们将变为:
fst @ (Int,Int) (fst @ ((Int,Int),Int) ((1,2),3))
Run Code Online (Sandbox Code Playgroud)
可以使用不同的类型twice,要求参数必须是多态函数.这需要Rank2Types:
twice' :: (forall a b . (a, b) -> a) -> ((a,b),c) -> a
twice' f x = f ( f x )
Run Code Online (Sandbox Code Playgroud)
但是,上面的函数用途有限,因为唯一有意义的选择f是fst- 没有其他类型的终止函数(forall a b . (a, b) -> a).
也应该可以使用类型类,开启一些扩展.
class C a where
type Res a
theF :: a -> Res a
instance C (a, b) where
type Res (a, b) = a
theF = fst
twiceC :: (C a, C (Res a)) => a -> Res (Res a)
twiceC x = theF (theF x)
Run Code Online (Sandbox Code Playgroud)
但是,这里必须在函数中定义函数instance,而不是作为参数传递.