PureScript - 无法将 Maybe String 类型与 String 类型匹配
PureScript - Could not match type Maybe String with type String
以下 PureScript 代码尝试记录字符串数组中的单个值
module Main where
import Effect (Effect)
import Effect.Console (log)
import Prelude
import Data.Array
x :: Array String
x = ["Jason","Zack","Billy","Trini","Kimberly"]
y :: String
y = x !! 2
main ∷ Effect Unit
main = do
log (y)
但是它会产生以下错误代码:
Could not match type
Maybe String
with type
String
while checking that type Maybe String
is at least as general as type String
好像是这行代码
y = x !! 2
Returns 一个 Maybe String
而不是一个 String
.
所以问题是,
如何将Maybe String类型转成String类型(过程中提供默认值)
是否有任何其他方法来访问 returns 一个字符串而不是可能字符串的数组(在本例中为字符串数组)?
要将 Maybe a
转换为 a
以在过程中提供默认值,请使用 fromMaybe
:
y :: String
y = x !! 2 # fromMaybe ""
专业提示:如果您正在寻找特定形状的函数,您可以通过函数签名搜索 Pursuit。例如,如果您对泛型感到不舒服,您可能已经通过 searching for a -> Maybe a -> a
. Or even more specifically search for String -> Maybe String -> String
发现了 fromMaybe
(尽管诚然,在这种情况下,fromMaybe
在页面上显得有点低)。
如果您正在寻找“任何其他方式”来访问数组并获得 String
,您必须问问自己:当数组少于三个元素时会发生什么?如果你要求数组中的第三个字符串,但它只包含两个,结果应该是什么?
显然没有理智的答案,这就是为什么 index
函数 returns a Maybe
.
另一种选择(FP 语言通常倾向于避免)是在这种情况下导致灾难性的运行时错误。这样的功能将被称为“部分”功能,这意味着它仅适用于 一些 输入而不适用于 所有可能的 输入。图书馆确实提供 some partial functions on arrays in Data.Array.Partial
,但 index
不是其中之一。我的猜测是,从来没有人需要它。
如果你真的想要,你可以自己制作:
unsafeIndex :: forall a. Array a -> Int -> a
unsafeIndex arr idx =
unsafePartial
case arr !! idx of
Just a -> a
这里我使用的 case
表达式不包含所有可能性(即没有 Nothing
情况),这通常会导致编译错误,但后来我使用 magic unsafePartial
function 摆脱它(或者更确切地说,将其推迟到运行时)。在运行时,如果给定无效索引,此函数将崩溃并提示“模式匹配失败”。
或者,我可以处理 Nothing
情况,但明确地崩溃而不是返回值。这样我就可以提供自定义错误消息:
unsafeIndex :: forall a. Array a -> Int -> a
unsafeIndex arr idx =
case arr !! idx of
Just a -> a
Nothing -> unsafeCrashWith "Array is too short"
总而言之,我想重申,即使可以使用这样的偏函数,您还是应该尽可能避免使用它们。类型系统的存在是为了 帮助 你,而不是阻碍你,如果你选择绕过它,你就是搬起石头砸自己的脚。
以下 PureScript 代码尝试记录字符串数组中的单个值
module Main where
import Effect (Effect)
import Effect.Console (log)
import Prelude
import Data.Array
x :: Array String
x = ["Jason","Zack","Billy","Trini","Kimberly"]
y :: String
y = x !! 2
main ∷ Effect Unit
main = do
log (y)
但是它会产生以下错误代码:
Could not match type
Maybe String
with type
String
while checking that type Maybe String
is at least as general as type String
好像是这行代码
y = x !! 2
Returns 一个 Maybe String
而不是一个 String
.
所以问题是,
如何将Maybe String类型转成String类型(过程中提供默认值)
是否有任何其他方法来访问 returns 一个字符串而不是可能字符串的数组(在本例中为字符串数组)?
要将 Maybe a
转换为 a
以在过程中提供默认值,请使用 fromMaybe
:
y :: String
y = x !! 2 # fromMaybe ""
专业提示:如果您正在寻找特定形状的函数,您可以通过函数签名搜索 Pursuit。例如,如果您对泛型感到不舒服,您可能已经通过 searching for a -> Maybe a -> a
. Or even more specifically search for String -> Maybe String -> String
发现了 fromMaybe
(尽管诚然,在这种情况下,fromMaybe
在页面上显得有点低)。
如果您正在寻找“任何其他方式”来访问数组并获得 String
,您必须问问自己:当数组少于三个元素时会发生什么?如果你要求数组中的第三个字符串,但它只包含两个,结果应该是什么?
显然没有理智的答案,这就是为什么 index
函数 returns a Maybe
.
另一种选择(FP 语言通常倾向于避免)是在这种情况下导致灾难性的运行时错误。这样的功能将被称为“部分”功能,这意味着它仅适用于 一些 输入而不适用于 所有可能的 输入。图书馆确实提供 some partial functions on arrays in Data.Array.Partial
,但 index
不是其中之一。我的猜测是,从来没有人需要它。
如果你真的想要,你可以自己制作:
unsafeIndex :: forall a. Array a -> Int -> a
unsafeIndex arr idx =
unsafePartial
case arr !! idx of
Just a -> a
这里我使用的 case
表达式不包含所有可能性(即没有 Nothing
情况),这通常会导致编译错误,但后来我使用 magic unsafePartial
function 摆脱它(或者更确切地说,将其推迟到运行时)。在运行时,如果给定无效索引,此函数将崩溃并提示“模式匹配失败”。
或者,我可以处理 Nothing
情况,但明确地崩溃而不是返回值。这样我就可以提供自定义错误消息:
unsafeIndex :: forall a. Array a -> Int -> a
unsafeIndex arr idx =
case arr !! idx of
Just a -> a
Nothing -> unsafeCrashWith "Array is too short"
总而言之,我想重申,即使可以使用这样的偏函数,您还是应该尽可能避免使用它们。类型系统的存在是为了 帮助 你,而不是阻碍你,如果你选择绕过它,你就是搬起石头砸自己的脚。