在同一个函数中处理多个不同的数据类型



在haskell中,是否可以创建一个能够处理多种不同输入和输出数据类型的函数?

例如,让我们假设一个函数能够对[Char]和Int进行模式匹配,分别返回两种数据类型。

fun 1 = 2
fun "textIn" = "textOut"

这可能吗?

正如Willem Van Onsem指出的,你可以用一个类型类做一些事情:

class Fun a where
fun :: a -> a
instance Fun Integer where
fun 1 = 2
instance Fun String where
fun "textIn" = "textOut"

这是否合理取决于具体情况。设计好的类是困难的,我强烈建议Haskell初学者完全避开它。从学习设计自己的函数和类型开始,并声明标准/库类的实例。


freestyle指出,您可以使用代数数据类型(adt)做一些事情,我认为这是一个更好的起点。

data Funny
= FunnyInteger Integer
| FunnyString String
deriving Show -- so you can print these in GHCi
fun :: Funny -> Funny
fun (FunnyInteger 1) = FunnyInteger 2
fun (FunnyString "textIn") = FunnyString "textOut"

freestyle还提到了广义代数数据类型(gadt)。这些绝对不适合初学者,但作为对未来的提示…

data FooTy a where
FooInteger :: FooTy Integer
FooString :: FooTy String
foo :: FooTy a -> a -> a
foo FooInteger 1 = 2
foo FooString "textIn" = "textOut"

By classTypeable:

{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad
import Data.Typeable
import Data.Foldable
fun :: Typeable a => a -> Maybe a
fun x = asum $ map ($x)
[ appT $ (x::Int) -> 2 <$ guard (x == 1)
, appT $ (x::String) -> "textOut" <$ guard (x == "textIn")
]
appT :: (Typeable a, Typeable b) => (b -> Maybe b) -> a -> Maybe a
appT f x = cast =<< f =<< cast x
main :: IO ()
main = do
print $ fun (1 :: Int)
print $ fun "textIn"
print $ fun [1 :: Int, 2]

输出:

Just 2
Just "textOut"
Nothing

appT是辅助函数(可能在某个包中)。您还可以看到:Dynamic,syb.

但这通常不是Haskell惯用的方式。

最新更新