RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1097920
Accepted
limitedeternity
limitedeternity
Asked:2020-03-22 06:32:19 +0000 UTC2020-03-22 06:32:19 +0000 UTC 2020-03-22 06:32:19 +0000 UTC

Haskell:是否可以将长度为 n 的列表的元素应用于函数?

  • 772

有这样一种情况:

  • 有一个功能fn :: Bool -> Bool -> Bool -> Bool。

  • 有一个由函数参数的可能值列表组成的列表fn:([[False, False, False], ... , [True, True, True]]由函数参数的数量生成)

我想在Python中实现类似“星号表达式”的东西:fn(*[a,b,...,z]) == fn(a,b,...,z) 并做这样的事情来获取所有“参数”列表的函数值:map (t $ fn) [[False, False, False], [True, True, True]]where t f [x,y,z] = f x y z.

问题是参数fn可能不是三个,而是或多或少。As 分别是 和 "argument" 列表中的元素。

如何实现一个函数t,以便它将具有可变数量元素的列表作为第二个参数?提前致谢!

编辑:

我达到了理想的解决方案,似乎:foldl a (\x -> \y -> \z -> z) [1,2,3]在哪里a = \f -> \x -> f x。让我们做一个 beta 减少:

  1. a (\x -> \y -> \z -> z) 1== (\x -> (\t -> \y -> \z -> z) x) 1==\y -> \z -> z
  2. a (\y -> \z -> z) 2== (\x -> (\y -> \z -> z) x) 2==\z -> z
  3. a (\z -> z) 3== (\x -> (\z -> z) x) 3==3

但:

    • Occurs check: cannot construct the infinite type: t0 ~ t0 -> t0
      Expected type: (t0 -> t0 -> t0 -> t0) -> t0 -> t0 -> t0 -> t0 -> t0
        Actual type: (t0 -> t0 -> t0 -> t0 -> t0)
                     -> t0 -> t0 -> t0 -> t0 -> t0
    • In the first argument of ‘foldl’, namely ‘a’
      In the second argument of ‘($)’, namely
        ‘foldl a (\ x -> \ y -> \ z -> z) [1, 2, 3]’
      In the second argument of ‘($)’, namely
        ‘show $ foldl a (\ x -> \ y -> \ z -> z) [1, 2, 3]’

查德特?

функции
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Fyodor Soikin
    2020-03-22T11:19:41Z2020-03-22T11:19:41Z

    “橡胶”curry当然可以。您的示例 cfoldl不起作用,因为每次迭代的结果必须是相同的类型,但您的类型不同:第一次迭代Bool -> Bool -> Bool,第二次Bool -> Bool,第三次Bool。

    但是 Haskell 有一种机制,允许您创建具有可变参数类型的函数。这种机制就是类。

    class CallWithBoolList f where
        t :: f -> [Bool] -> Bool
    

    这里f, 是您要使用列表中的参数调用的函数类型,并且t是您的搜索函数。它的第一个参数是一个函数f,它的第二个参数是一个参数列表,它返回f使用这些参数调用的结果。

    第一种情况是基本的:一个空的参数列表。在这种情况下,函数类型f简单地退化为Bool. 毕竟,没有参数的函数只是一个值。让我们写:

    instance CallWithBoolList Bool where
        t b [] = b
        t _ _ = error "Слишком много аргументов"
    

    请注意,如果您在此处传递非空列表,则会引发错误。我会回到这个。

    第二种情况是递归的:一个由头和尾组成的参数列表。在这种情况下,函数的类型f必须是Bool -> a,其中Bool是它的第一个参数,并且a是函数的“余数”,也就是说,一个函数需要除第一个参数之外的所有参数,然后返回一个值。让我们写:

    instance CallWithBoolList a => CallWithBoolList (Bool -> a) where
        t f (x:xs) = t (f x) xs
        t _ [] = error "недостаточно аргументов"
    

    在这里,函数t将第一个参数(列表的“头”)传递给函数f,该函数返回“函数的剩余部分”,然后将其t与其余部分一起传递给函数的“先前”版本参数(列表的“尾部”)。

    让我们检查一下它是如何工作的:

    f1 x = not x
    f2 x y = x && y
    f3 x y z = x && y && z
    f4 x y z w = x && y || z && w
    
    main = do
        print $ t f1 [True] -- выводит False
        print $ t f2 [True, False] -- выводит False
        print $ t f3 [True, False, True] -- выводит False
        print $ t f4 [True, True, False, False] -- выводит True
        print $ t f1 [True, False] -- ошибка: слишком много аргументов
    

    这种方法可以推广到任何类型,而不仅仅是Bool. 该类及其实现将如下所示:

    class CallWithList f res where
        t' :: f -> [res] -> res
    
    instance CallWithList res res where
        t' res [] = res
        t' _ _ = error "слишком много аргументов"
    
    instance CallWithList f res => CallWithList (res -> f) res where
        t' f (x:xs) = t' (f x) xs
        t' _ [] = error "недостаточно аргументов"
    

    唯一的区别是额外的变量res,它存在于类和实现中,替换了类型Bool。


    但是,看看你的评论,我怀疑这正是你想要的。特别要注意,在我的实现中,如果t使用“错误”数量的参数调用函数,则会引发错误。但是对于我在评论中关于在这种情况下应该发生什么的问题,您回答:

    fn这些“不是三个”元素必须作为论据进来。假设“不是三”是二。然后fn会有Bool -> Bool -> Bool

    这是不可理解的。例如,以下程序应该如何工作:

    main = do
        let f x y z = x && y && z
        print $ t f [True, False]
    

    在我的实现中,它会在运行时抛出一个错误。你在期待什么?

    假设你说这样的程序不应该编译。好的,然后让用户输入参数列表:

    main = do
        let f x y z = x && y && z
        args <- read <$> readLine
        print $ t f args
    

    然后怎样呢?不清楚。

    如果您指定您希望看到的确切内容,也许我可以提供更好的解决方案。

    • 5

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5