haskell多态类型函数

Mar*_*van 3 polymorphism haskell types parametric-polymorphism

在Haskell中有可能有一个可以采用多态类型并返回多态类型的函数吗?

例如,我想要一个接受值的函数,如果值是类型则返回一个Int,如果是类型则返回Foo一个StringBar

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"
Run Code Online (Sandbox Code Playgroud)

这样的事情可能吗?如果没有,基于类型路由到另一个函数的最佳实践是什么?

Car*_*ten 5

首先你描述的东西和Either Int String签名似乎不匹配 - 我会先尝试你描述的内容(按输入类型选择输出类型):

你可以做一些非常类似于我认为你尝试使用类型系列的东西:

{-# 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"
Run Code Online (Sandbox Code Playgroud)

例:

?> polyMap One
123
?> polyMap That
"string"
Run Code Online (Sandbox Code Playgroud)

一些解释

我认为你想要的是具有类型映射/函数(没有运行时的运行时检查,typeOf这会给你一些很好的类型检查支持),基本上有两种方法可以做到(我我知道)

两者都给你(以及其他)有方法可以说:看看我是否得到类型AI可以说出某些相关类型B必须是什么(Foo -> IntBar -> String)

这是一个深层主题(borderline dependent-types;))但我认为带类的类型系列并不难理解.

我使用的想法是拥有PolyMap提供polyMap函数的类(你可以将它命名为你想要的任何东西doSomething,无论如何),输出类型依赖于输入类型,使用的To k映射是Intfor FooStringfor,Bar如实例中所述 -声明.


另一个为您的签名更容易:

doSomething :: Either Foo Bar -> Either Int String
doSomething (Left _) = Left 123
doSomething (Right _) = Right "string"
Run Code Online (Sandbox Code Playgroud)

例:

?> doSomething (Left One)
Left 123
?> doSomething (Right That)
Right "string"
Run Code Online (Sandbox Code Playgroud)