Cli*_*ton 1 haskell function-object
我正在尝试创建一个Func表示函数的类,然后创建一个Dot组成函数的数据类型.下面是我的尝试,但我收到编译错误:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GADTs #-}
module Func where
class Func f a b | f -> a, f -> b where
apply :: f -> a -> b
data Dot f1 f2 where
Dot :: (Func f1 a b, Func f2 b c) => f1 -> f2 -> Dot f1 f2
instance Func (Dot f1 f2) a c where
apply (Dot f1 f2) = (apply f2) . (apply f1)
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Func.hs:15:26:
Could not deduce (Func f2 b c) arising from a use of `apply'
from the context (Func f1 a1 b, Func f2 b c1)
bound by a pattern with constructor
Dot :: forall f1 f2 a b c.
(Func f1 a b, Func f2 b c) =>
f1 -> f2 -> Dot f1 f2,
in an equation for `apply'
at Func.hs:15:12-20
Possible fix:
add (Func f2 b c) to the context of
the data constructor `Dot'
or the instance declaration
In the first argument of `(.)', namely `(apply f2)'
In the expression: (apply f2) . (apply f1)
In an equation for `apply':
apply (Dot f1 f2) = (apply f2) . (apply f1)
Func.hs:15:39:
Could not deduce (Func f1 a b) arising from a use of `apply'
from the context (Func f1 a1 b, Func f2 b c1)
bound by a pattern with constructor
Dot :: forall f1 f2 a b c.
(Func f1 a b, Func f2 b c) =>
f1 -> f2 -> Dot f1 f2,
in an equation for `apply'
at Func.hs:15:12-20
Possible fix:
add (Func f1 a b) to the context of
the data constructor `Dot'
or the instance declaration
In the second argument of `(.)', namely `(apply f1)'
In the expression: (apply f2) . (apply f1)
In an equation for `apply':
apply (Dot f1 f2) = (apply f2) . (apply f1)
Run Code Online (Sandbox Code Playgroud)
我需要修复什么才能进行编译?
我意识到这看起来有点傻,但我认为能够将不同的函数作为唯一类型进行携带可能是有用的,因为可以将各种元数据附加到这些类型(我还不确定到底是什么).
问题是实例头Func (Dot f1 f2) a c不能"查看" f1并f2推断出功能依赖性.您需要自己完成这项工作,使用等效配方会更容易
{-# LANGUAGE TypeFamilies #-}
class Func f where
type FuncArg f :: *
type FuncRes f :: *
apply :: f -> FuncArg f -> FuncRes f
data Dot f1 f2 where
Dot :: (Func f1, Func f2, FuncArg f2~FuncRes f1)
=> f1 -> f2 -> Dot f1 f2
instance Func (Dot f1 f2) where
type FuncArg (Dot f1 f2) = FuncArg f1
type FuncRes (Dot f1 f2) = FuncRes f2
apply (Dot f1 f2) = (apply f2) . (apply f1)
Run Code Online (Sandbox Code Playgroud)
或者你有什么特别的理由喜欢fundeps而不是类型系列吗?