haskell - 类型相等函数

标签 haskell

有没有办法像这样定义一个函数:

f :: (C a, C b) => a -> Maybe b

这样:

f = Just

当输入a = b时,并且

f _ = Nothing

何时输入a/= b

请注意:

  • 我不想使用重叠的实例。
  • 我不希望有类约束 C,但我非常确定它是必要的(特别是如果我想避免重叠实例)。
  • 我想在此方案中为要比较的每种类型仅定义一个实例,定义一个类 Equal a b 使这个问题变得微不足道,但它需要 n^2 code> 我想避免的实例。

最佳答案

就这样

http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Typeable.html#v:cast

cast :: (Typeable a, Typeable b) => a -> Maybe b

使用示例

函数转换可以是“像面向对象语言这样的类型转换系统”的一部分。细菌和真菌是生命。他们可以被提升到生命。生命也许能够转化为细菌或真菌。

{-# LANGUAGE ExistentialQuantification, DeriveDataTypeable #-}

import Data.Typeable
import Data.Maybe

data SomeLife = forall l . Life l => SomeLife l
        deriving Typeable

instance Show SomeLife where
        show (SomeLife l) = "SomeLife " ++ show l

class (Typeable l, Show l) => Life l where
        toLife :: l -> SomeLife
        fromLife :: SomeLife -> Maybe l

        toLife = SomeLife
        fromLife (SomeLife l) = cast l

instance Life SomeLife where
        toLife = id
        fromLife = Just

data Bacteria = Bacteria deriving (Typeable, Show)

instance Life Bacteria

data Fungus = Fungus deriving (Typeable, Show)

instance Life Fungus

castLife :: (Life l1, Life l2) => l1 -> Maybe l2
castLife = fromLife . toLife

filterLife :: (Life l1, Life l2) => [l1] -> [l2]
filterLife = catMaybes . map castLife

withLifeIO :: (Life l1, Life l2) => l1 -> (l2 -> IO ()) -> IO ()
withLifeIO l f = maybe (return ()) f $ castLife l

withYourFavoriteLife :: Life l => (l -> IO ()) -> IO ()
withYourFavoriteLife act = do
        withLifeIO Bacteria act
        withLifeIO Fungus act

main :: IO ()
main = do
        let     sls :: Life l => [l]
                sls = filterLife [
                        SomeLife Bacteria,
                        SomeLife Fungus,
                        SomeLife Fungus ]
        print (sls :: [SomeLife])
        print (sls :: [Bacteria])
        print (sls :: [Fungus])
        withYourFavoriteLife (print :: SomeLife -> IO ())
        withYourFavoriteLife (print :: Bacteria -> IO ())
        withYourFavoriteLife (print :: Fungus -> IO ())

该技术扩展到类型层次结构系统。一生模块就在这里。 https://github.com/YoshikuniJujo/test_haskell/blob/master/features/existential_quantifications/type_hierarchy/Life.hs

异常系统使用这种技术。 https://hackage.haskell.org/package/base-4.9.1.0/docs/Control-Exception.html

关于haskell - 类型相等函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44647096/

相关文章:

haskell - 如何结合二元和一元函数来获得折叠的阶跃函数?

haskell - Haddock - 在记录类方法时尝试使用命名 block

haskell - 如何对关联数据进行约束?

haskell - 如何编写 Control.Lens.AT 的实例

haskell - 如何在 Esqueleto 查询中使用 Group By 和 Sum

unit-testing - 如何测试抽象数据类型?

haskell - 只导入模块的部分功能有什么影响

haskell - (共)递归定义如何在 Haskell 中工作?

haskell - Haskell 中的封闭类型族和类型推断

haskell - 将 Haskell 运算符作为值处理