[英]haskell polymorphic type functions
Is it possible in Haskell to have a function that can take a polymorphic type and return a polymorphic type? 在Haskell中有可能有一个可以采用多态类型并返回多态类型的函数吗?
For example, I want a function that takes a value, and returns an Int if the value is of type Foo
and a String if it is of type Bar
例如,我想要一个获取值的函数,如果值是Foo
类型则返回Int,如果类型是Bar
,则返回String
data Foo = One | Two | Three deriving (Show, Read)
data Bar = This | That | TheOther deriving (Show, Read)
doSomething :: Either Foo Bar -> Either Int String
doSomething var = if (typeOf var) == Int then 123 else "string"
Is something like this possible? 这样的事情可能吗? If not, what is the best practice for routing to another function based on type? 如果没有,基于类型路由到另一个函数的最佳实践是什么?
first the things you describe and the Either Int String
signature seem not to match - I'll try what you describe first (choose the output-type by it's input type): 首先你描述的东西和Either Int String
签名似乎不匹配 - 我会先尝试你描述的内容(按输入类型选择输出类型):
you can do something very similar to what I think you are trying with type-families: 你可以做一些非常类似于我认为你尝试使用类型系列的东西:
{-# LANGUAGE TypeFamilies #-}
module SO where
data Foo = One | Two | Three deriving (Show, Read)
data Bar = This | That | TheOther deriving (Show, Read)
class PolyMap k where
type To k :: *
polyMap :: k -> To k
instance PolyMap Foo where
type To Foo = Int
polyMap _ = 123
instance PolyMap Bar where
type To Bar = String
polyMap _ = "string"
example: 例:
λ> polyMap One
123
λ> polyMap That
"string"
What I think you want is to have type-mappings/functions (there is no runtime check with typeOf
out-of-the box and this would give you some nice type-checking support instead) and there are basically two ways to do it (I am aware of) 我认为你想要的是具有类型映射/函数(没有运行时检查与typeOf
开箱即用,这将为你提供一些很好的类型检查支持),基本上有两种方法(我知道)
Both give you (among others) the means to have some way to say: look if I get type AI can say what some associated type B must be ( Foo -> Int
and Bar -> String
) 两者都给你(以及其他)有一些方法可以说:看看我是否得到类型AI可以说一些相关类型B必须是什么( Foo -> Int
和Bar -> String
)
This is a deep topic (borderline dependent-types ;)) but I think type-families with classes are not to hard to understand. 这是一个深层主题(borderline dependent-types;))但我认为带类的类型系列并不难理解。
The idea I used is to have the class PolyMap
that provides the polyMap
function (you can have it named anything you want - doSomething
, whatever) and there the output type depends on the input type using the To k
mapping which is Int
for Foo
and String
for Bar
as stated in the instance-declarations. 我以前的想法是有类PolyMap
,提供了polyMap
功能(你可以把它命名为任何你想要的- doSomething
,不管),而且输出类型,使用依赖于输入型To k
映射是Int
了Foo
和Bar
String
,如实例声明中所述。
the other one for your signature is even easier: 另一个为您的签名更容易:
doSomething :: Either Foo Bar -> Either Int String
doSomething (Left _) = Left 123
doSomething (Right _) = Right "string"
example: 例:
λ> doSomething (Left One)
Left 123
λ> doSomething (Right That)
Right "string"
You can put doSomething
in a typeclass keyed on both the domain and the codomain types, with a functional dependency from the domain to the codomain: 你可以将doSomething
放在一个键控在域和codomain类型的类型类中,并具有从域到codomain的功能依赖:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-} -- if one of your `to` really is `String`
class DoSomething from to | from -> to where
doSomething :: from -> to
instance DoSomething Foo Int where -- ...
instance DoSomething Bar String where -- ...
Compared with the type family-based solution, this has the benefit that if the codomain also uniquely determines the domain , you can add another functional dependency to -> from
. 与基于类型族的解决方案相比,这样做的好处是, 如果codomain也唯一地确定了域 ,则可以to -> from
添加另一个函数依赖项。 I don't think type families offer a good way of modelling that. 我不认为类型系列提供了一种很好的建模方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.