如何在 Haskell 中创建异构列表? (最初是Java)

2024-06-22

如何将以下 Java 实现转换为 Haskell?

这里的主要目的是拥有一个包含作为特定接口的子类型的各种元素的列表。
我尝试制作下面的 Haskell 版本,但未能达到我的目的。 这里的重点是xs有类型[Bar]而不是Foo a => [a]

这是否意味着 Haskell 不能做到这一点,我应该以另一种方式思考吗?

Java

interface Foo {
    void bar ();
}

public class Bar1 implements Foo {
    @Override
    public void bar() {
        System.out.println("I am bar 1 class");
    }   
}

public class Bar2 implements Foo {
    @Override
    public void bar() {
        System.out.println("I am bar 2 class");
    }   
}

public static void main(String[] args) {
    // The major purpose here is having a list 
    // that contains elements which are sub-type of "Foo"
    List<Foo> ys = new ArrayList<Foo>();

    Foo e1 = new Bar1();
    Foo e2 = new Bar2();

    ys.add(e1);
    ys.add(e2);

    for (Foo foo : ys) {
        foo.bar();
    }
}

Haskell

class Foo a where
  bar :: a -> IO ()

data Bar = Bar1 | Bar2

instance Foo Bar where
  bar Bar1 = print "I am Bar1"
  bar Bar2 = print "I am Bar2"

--xs :: Foo a => [a]
xs :: [Bar]
xs = [Bar1, Bar2]

main :: IO ()
main = mapM_ bar xs

简单回答:don't! Haskell 不是面向对象语言,假装它是面向对象语言并试图将继承模式转换为类型类和 ADT 的混合体并没有多大用处。 https://stackoverflow.com/questions/20184286/object-oriented-programming-in-haskell/20188103#20188103.

Your List<Foo>在 Java 中与Foo a => [a]在 Haskell 中:这样的签名实际上意味着forall a . Foo a => [a]. The a基本上是函数的额外参数,即它可以从外部选择特定的Foo这里使用的是实例。

Quite the opposite in Java: there you don't have any control of what types are in the list at all, only know that they implement the Foo interface. In Haskell, we call this an existential type, and generally avoid it because it's stupid. Ok, you disagree – sorry, you're wrong!
...No, seriously, if you have such an existential list, the only thing you can ever do1 is execute the bar action. Well, then why not simply put that action in the list right away! IO() actions are values just like anything else (they aren't functions; anyway those can be put in lists just as well). I'd write your program

xs :: [IO ()]
xs = [bar Bar1, bar Bar2]

That said, if you absolutely insist you can have existential lists in Haskell as well:
{-# LANGUAGE ExistentialQuantification #-}

data AFoo = forall a. Foo a => AFoo a

xs :: [AFoo]
xs = [AFoo Bar1, AFoo Bar2]

main = mapM_ (\(AFoo f) -> bar f) xs

因为这已经成为一种咆哮:我确实承认 OO 风格对于某些应用程序来说比 Haskell 的函数式风格更方便。存在确实有其有效的用例(不过,像 chunksOf 50 一样,我更喜欢将它们写为GADTs http://www.haskell.org/haskellwiki/GADTs_for_dummies)。只是,对于很多问题,Haskell 允许提供更简洁、更强大、更通用的解决方案,但在许多方面比您在 OO 编程中使用的“如果您只有一把锤子……”继承更简单,因此在使用存在性之前,您需要应该对 Haskell 的“原生”功能有一个正确的感觉。


1Yeah, I know you can also do "typesafe dynamic casts" etc. in Java. In Haskell, there's the Typeable class for this kind of stuff. But you might as well use a dynamic language right away if you take such paths.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Haskell 中创建异构列表? (最初是Java) 的相关文章

  • 为什么以下内容会并行运行而不是顺序运行?

    给定以下函数evalPair parPair and deepSeq分别 evalPair Strategy a gt Strategy b gt Strategy a b evalPair sa sb a b do a lt sa a b
  • Haskell:GHC 无法推断类型。由类型签名错误绑定的刚性类型变量

    我看过几篇主题相似的帖子 但它们并不能真正帮助我解决我的问题 所以我才敢重复 现在我有一个带有签名的函数 run Expr query gt RethinkDBHandle gt query gt IO JSON 这是一个数据库查询运行函数
  • 如何处理或避免BlockedIndefinitelyOnSTM异常?

    我花了很多时间来解决我正在处理的应用程序中遇到的问题 该应用程序是一个 Web 应用程序 使用 scotty 公开 REST 端点 它使用一个TVar保持其更新的状态STM a由前端层触发的动作 由于该应用程序基于事件溯源原则 因此业务层生
  • Haskell - 翻转具有两个参数的类型类的参数

    我有一个多参数类型类 它提供了一个可以交换其参数的函数 class Swappable a b where swappable a gt b gt Bool So if a and b form Swappable a b then b a
  • Haskell:从后面访问列表

    今天我开始学习Haskell 我对函数式语言有点陌生 而且我非常喜欢 Haskell 然而 我有一个关于它的设计的问题困扰着我 从我到目前为止的理解来看 访问列表后面的元素似乎比访问前面的元素要复杂得多 类似于xs x where xs a
  • 作为应用函子(Haskell / LYAH)

    第11章向你学习 Haskell引入以下定义 instance Applicative gt r where pure x gt x f lt gt g x gt f x g x 在这里 作者进行了一些不寻常的挥手 的实例实现有点神秘 所以
  • 如何在 GHCJS 程序中定期执行操作?

    应该有人使用setInterval通过Javascript 或者使用一些更惯用的基于线程的解决方案 Using setInterval posed 一些挑战 https stackoverflow com questions 3357661
  • 对参数进行排序以利用柯里化

    我最近两次重构代码以更改参数的顺序 因为代码太多 黑客喜欢flip or x gt foo bar x 42正在发生 在设计函数签名时 哪些原则可以帮助我充分利用柯里化 对于轻松支持柯里化和部分应用的语言 有一系列令人信服的论点 最初来自
  • 使用 GHC.Generics 恢复类型定义

    昨天我尝试回答这个问题是关于数据类型的表示 https stackoverflow com questions 22715572 a serializable representation of a data type for client
  • 为什么 Kleisli 不是 Monoid 的一个实例?

    如果您希望附加两个类型 a gt m b 的函数 以便只得到一个附加两个结果的相同类型的函数 您可以使用 Kleisli 来执行此操作 instance Monad m Monoid b gt Monoid Kleisli m a b wh
  • Haskell 中存在量化值的列表

    我想知道为什么这段代码不进行类型检查 LANGUAGE ScopedTypeVariables Rank2Types RankNTypes OPTIONS fglasgow exts module Main where foo forall
  • 无法让 wxHaskell 在 Mac 上从 ghci 工作

    我正在尝试跑步一个例子 http www haskell org haskellwiki WxHaskell Quick start Hello world in wxHaskell using EnableGUI function htt
  • Haskell 中的随机枢轴快速排序

    是否有可能在 Haskell 中实现快速排序 使用 RANDOM PIVOT 但仍然有一个简单的Ord a gt a gt a 签名 我开始了解 Monad 目前 我将 monad 解释为某种 命令模式 这对于 IO 非常有用 所以 我知道
  • 自动函子实例

    给定以下代数类型 ghci gt data Foo a Foo a 然后我实例化其中之一 ghci gt let f Foo foo 最后 我想打电话给fmap将函数应用为 a gt b gt Foo a gt Foo b ghci gt
  • 当您包含导入 Gloss 的项目时,“stack ghci”会失败

    如果您在 Stack 项目中导入 Gloss 并使用stack ghci 您会收到以下错误 GHCi version 7 10 2 http www haskell org ghc for help
  • 为什么 Haskell 没有 I Monad(仅用于输入,与 IO monad 不同)?

    从概念上讲 执行输出的计算似乎与仅执行输入的计算有很大不同 从某种意义上说 后者更为纯粹 就我而言 我希望有一种方法将程序中仅输入的部分与可能实际写出内容的部分分开 那么 为什么没有输入只有 Monad 呢 为什么拥有一个 I monad
  • Haskell 中有“对象平等”的感觉吗?

    如果我在 Haskell 中有一个单链表 data LL a Empty Node a LL a deriving Show Eq 我可以轻松实现在末尾和开头插入的方法 但是在特定元素之后或之前插入又如何呢 如果我有一个LL of Inte
  • 如何构图“也许”镜头?

    如果我有嵌套记录的镜头 其中每个镜头返回一个Maybe 我怎样才能让它们组合起来 这样如果 遍历 中有任何东西返回一个Nothing最终结果是Nothing data Client Client clientProperties Maybe
  • 从 SQL 数据库反序列化数据

    我有一个小应用程序 由数据库支持 SQLite 但它与问题并不真正相关 我定义了一些类型 例如 data Whatever Whatever Int Int String String data ImportantStuff Importa
  • 当测试文件定义为模块时,使用堆栈调用 hspec 定义的测试会抛出错误

    我试图弄清楚为什么包含定义为模块的单元测试的测试文件在运行时失败stack build test 假设有一个从头开始定义的简单测试模块 stack new test module cd test module vim package yam

随机推荐

  • 为什么 gcc 和 clang 会为此程序产生不同的输出? (转换运算符与构造函数)

    program include
  • 正则表达式 Django url

    你好 我有一个 url 我想匹配 uuid 网址如下所示 移动 移动事物 68f8ffbb b715 46fb 90f8 b474d9c57134 urlpatterns patterns mobile views url r someth
  • jsf 在方法表达式中传递参数在 ViewScoped bean 中失败

    我有一个由 ViewScoped bean 支持的 jsf 页面 其中列出了一堆事务 如下所示
  • 在 C 中用数组制作 switch 语句?

    我正在尝试制作一个 switch 语句 将一个单词放入数组中 然后通过 switch 语句抛出每个字母 并根据每个字母是哪个字母为每个字母分配一个点 并给出该单词的最终点值 我似乎无法正确获取数组部分 任何帮助 将不胜感激 int main
  • Kdiff3 无法使用 mergetool 命令打开

    我有冲突 所以我输入 git mergetool 然后我收到一条消息说 按回车键启动合并解析工具 通常 当我这样做时 它会打开 kdiff3 以便我可以合并差异 现在 当我这样做时 它只是继续到下一个文件 并且 kdiff3 根本不打开 我
  • 打开 localhost 时权限被拒绝

    我最近在 Ubuntu 中安装了 Apache PHP 和 MySQL 并将我创建的文件复制到var www目录 但当我打开http localhost它正在显示 警告 未知 无法打开流 第 0 行未知中的权限被拒绝 致命错误 未知 无法打
  • PHP无法回显数据

    我正在尝试从数据库获取数据 并使用它们的唯一 ID 在页面上回显它们 下面是我的代码
  • 页面刷新时随机更改 HTML 背景

    我知道这个主题已经被浏览了很多次 但我希望我的主页随机选择一个图像 然后更改该图像的副标题 我的网站的网址是 http www connorloughlin com http www connorloughlin com 页面底部有一个小标
  • Pandas 按名称对列进行排序

    我有以下数据框 我想根据名称对列进行排序 1 13 1 13 10 13 2 2 3 9 31 2 1 3 4 我尝试按以下方式对列进行排序 1 2 3 13 1 13 2 13 10 9 3 4 31 1 2 我一直在尝试使用解决这个问题
  • Date.toLocaleString() 的 Chrome 时区选项

    我最近发现 JavaScript 有一个新的扩展 这增加了几个功能Date对象在toLocaleString toLocaleDateString and toLocaleTimeString功能 参考这里 https developer
  • #include 未找到

    我已经从源代码编译了 FreeImage 并安装了它 当我跑步时sudo make install在我的系统上安装以下文件 usr local include FreeImage h usr local lib libfreeimage 3
  • 通过在 Microsoft Bot Framework 中循环文件来动态创建卡片

    我一直在尝试 Microsoftbot dialog showShirts function session var msg new builder Message session msg attachmentLayout builder
  • 如何将所有键和值从 Swift 中的 NSDictionary 获取到单独的字符串数组中?

    let urlAsString https drive google com uc export download id 0B2bvUUCDODywWTV2Q2IwVjFaLW8 let url NSURL string urlAsStri
  • java如何存储文字?

    System out println 5678 该文字直接用在打印语句中 但是java是直接将其存储在内存中还是创建一个自动变量然后将其存储在那里 如果第二种情况成立 如果有人碰巧使用相同的变量名意外访问该变量 会发生什么情况 解释 Jav
  • Chrome 扩展程序上传错误 - default_locale 缺失

    每当我尝试将更新的扩展程序上传到 Chrome Web Store 时 我都会收到 清单中缺少 default locale 字段 的消息 错误 但它清楚地位于我的清单中 粘贴在下面 有关如何解决此问题的任何指示吗 manifest ver
  • Google Storage python api并行下载

    使用以下命令并行下载大量文件到本地计算机是很简单的gsutil https cloud google com storage docs gsutil commands cp通过添加 m flag gsutil m cp gs my buck
  • 安装 Anaconda Python 时发生冲突

    我最近安装了 Python 的 Anaconda 发行版 然后我将以下行插入到我的 bashrc file export PATH home karnivaurus Libraries Anaconda bin PATH 所以 现在有两个p
  • 添加图层后,播放按钮不会出现在 AVPlayer 中 - iOS 16

    我正在使用 AVPlayer 来呈现视频 该应用程序只有一个 mp4 但对于不同的用例 需要翻转相同的视频 按钮在那里并且功能齐全 您可以按播放和 15 秒前进 后退按钮 但它们不会出现在屏幕上 附图中的第四个视频 问题似乎是我添加的翻转层
  • 将数据传递到 Vue 模板

    我对 vue 相当陌生 不知道如何在模板中添加数据值 我正在尝试构建一个非常基本的表单生成器 如果我单击一个按钮 它应该将另一个数据数组添加到组件变量中 这是有效的 我正在执行 v for 来添加输入字段 其中某些属性是该组件的数组的一部分
  • 如何在 Haskell 中创建异构列表? (最初是Java)

    如何将以下 Java 实现转换为 Haskell 这里的主要目的是拥有一个包含作为特定接口的子类型的各种元素的列表 我尝试制作下面的 Haskell 版本 但未能达到我的目的 这里的重点是xs有类型 Bar 而不是Foo a gt a 这是