有没有办法在 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/