haskell - 在 Haskell 中展开函数类型

标签 haskell

有没有办法在 Haskell 中解开以下类型?

newtype Rand a = Rand(StdGen -> (a , StdGen))

我有一个返回此类型的函数,还有另一个函数,我想使用返回函数中的“a”值,但我不知道如何提取该值。

最佳答案

当你写下:

newtype Rand a = Rand(StdGen -> (a , StdGen))

了解您正在写的内容非常重要。

在这种情况下,newtype 相当于data(唯一需要注意的是newtype 效率更高)。因此,我们也可以像这样编写类型定义:

data Rand a = Rand (StdGen -> (a, StdGen))

一点一点:

Type constructor
      |              ..-- Type parameter
     \|/       ..--''
      '   .--''
data Rand a = Rand (StdGen -> (a, StdGen))
               .   '---------------------'
              /|\              |
               |               '- Wrapped data
     Data constructor

首先,让我们看一个更简单的示例:

data Sum = Sum Int

注释:

Type constructor
      |
     \|/
      '
data Sum = Sum Int
            .  '-'
           /|\  '--- Wrapped data
            |
     Data constructor

为了更清楚,我们将区分类型(构造函数)和(数据)构造函数:

data SumType = SumCon Int

现在,我们如何提取值 x::SumType 中保存的 Int

显而易见的选择是模式匹配:

getSum :: SumType -> Int
getSum (SumCon n) = n

这有效。但这是一件非常常见(而且微不足道)的事情 - 为了使它更容易,引入了“记录语法”。这意味着我们可以像这样重写我们的类型:

data SumType = SumCon { getSum :: Int }

现在我们不必再手动编写 getSum ——编译器会为我们做这件事,这意味着我们可以假设一个函数 getSum::SumType -> Int存在。

现在,让我们回到Rand a:

newtype Rand a = Rand (StdGen -> (a, StdGen))

我们可以手动编写:

getRand :: Rand a -> (StdGen -> (a, StdGen))
getRand (Rand f) = f

或者让编译器为我们做这件事:

newtype Rand a = Rand { getRand :: StdGen -> (a, StdGen) }

关于haskell - 在 Haskell 中展开函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27283002/

相关文章:

haskell - 为 GADT 定义您自己的 Typeable 实例

haskell - 将系统命令的结果绑定(bind)到 Haskell 中的变量

Haskell 对(位 a)推断类型错误的困惑

haskell - UndecidableInstances 和 newtypes

haskell - ghc 7.4.1 不生成 stub.o 文件

haskell - 什么时候在 Haskell 中使用 "strict wildcard"有用,它有什么作用?

haskell - 在 Haskell 中编写数学表达式的惯用方式

list - Haskell 将元组列表映射到元组列表

haskell "pseudo-functor"

javascript - 如何使用算法 W 键入检查递归定义?