Ad hoc多态函数

时间:2017-09-26 18:09:40

标签: haskell functional-programming

我有一些我想要打印的数据(有些是可能的,有些则不是),我正在尝试创建一个通用的showField函数,如下所示:

user_block_ranges

这会引发严格的错误:

block_range

我一般都明白这个错误,但我不明白是否有办法实现我想要的。我也尝试过模式匹配而不是守卫,但也不能完全解决问题。我能用这种格式构建一些可行的东西吗?

2 个答案:

答案 0 :(得分:11)

看起来你正在尝试构建一个adhoc多态函数 - 一个函数,其定义根据其类型而变化。

参数化多态函数对所有数据类型都做同样的事情:

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';


body { 
  padding: 0; 
  margin: 0; 
  font-family: Roboto, sans-serif; 

}

在Haskell中,adhoc多态性是使用类型类实现的:

both :: a -> (a,a)
both a = (a,a)

但是,没有办法为类型为“Maybe a”的所有其他类型定义一个实例,所以你只需要为你真正关心的类型定义实例:

class ShowField a where
  showField :: a -> Text

instance Show a => ShowField (Maybe a) where
  showField Nothing = "None"
  showField (Just a) = Text.pack $ show a

您可以使用class ShowField Int where showField = Text.pack . show class ShowField Float where showField = Text.pack . show

来减少样板
-XDefaultSignatures

答案 1 :(得分:1)

错误告诉我们:

print("Go!")

def check():
    import time
    from threading import Thread
    answer=input()
    answer = None
    time.sleep(9.58)
    if answer != None:
        return
        distance=answer.count
        print ("And he crosses the line with...",distance)
    Thread(target = check).start()

    answer = input("1")
check()

基本上,这告诉我们根据您提供的类型签名,第一个参数的类型是‘a’ is a rigid type variable bound by the type signature for: showField :: forall a. Show a => a -> Text (签名隐含“forall a. Show a”位),这意味着第一个参数可以是forall a.的实例的任何类型。它是刚性类型变量,因为它由显式类型签名定义。

它还告诉我们:

Show

通过将Couldn't match expected type ‘Maybe a0’ with actual type ‘a’ isJust两种类型isNothing - 应用于第一个参数,您还声称第一个参数的类型为Maybe a -> Bool,这是显然与Maybe a的类型不同。

您可以通过删除forall a. Show a => a -> Text的类型签名将其转换为正确的程序,但这不会有您想要的行为 - 推断的类型签名将是showField,显然只接受值(Show a) => Maybe a -> Text(其中Maybe a也是a的实例)。

在Haskell中,你不能拥有一个接受Showa¹值的函数。没有更多的背景,目前还不清楚你的实际目标是什么,但几乎可以肯定有一种更为惯用的方法来实现它。

¹除非您的类型类包含Maybe aa的实例。