导入分配的外部函数时是否需要使用IO?

fra*_*ale 5 haskell allocation ffi

在Haskell中,使用FFI绑定到分配功能时,它是适当的避免使用IO时的外部函数分配并构建了一些值,并将该值依赖于函数的参数?

考虑以下功能:

/**
 * The foo_create contract: if allocation succeeds, the
 * return value points to a value that depends only on 'x'
 * and 'name', otherwise a null pointer is returned.
 */
foo_t *foo_create(int x, const char *name);
Run Code Online (Sandbox Code Playgroud)

以下列方式导入此功能是否合适?

newtype Foo = Foo (Ptr Foo)

foreign import unsafe "foo.h foo_create"
foo_create :: CInt -> CString -> Ptr Foo
Run Code Online (Sandbox Code Playgroud)

然后可以包装此低级绑定函数以提供更好的API:

makeFoo :: CInt -> CString -> Maybe Foo
makeFoo x s =
  let
    ptr = foo_create x s
  in
    if ptr == nullPtr
      then Nothing
      else Just (Foo ptr)
Run Code Online (Sandbox Code Playgroud)

虽然分配会影响现实世界,但是它是否成功也取决于现实世界,该类型确实对可能的结果进行建模.此外,即使是纯函数和数据也可能导致Haskell运行时分配.那么,IO在这些情况下避免使用monad 是否合理?

Ben*_*Ben 8

如果foo_create回报,只有依赖于该值的价值xname,然后是它的外部的微小的返回值IO.正如你所说,在Haskell中创建新值会导致分配,并且它们不需要进入,IO因为不可能观察到在外部分配的特定内存地址,IO也无法观察分配是否成功(即是否成功)程序内存不足IO.

但是,你说"它是否成功也取决于现实世界".在这种情况下,不,它是一个有效的操作,应该有一个返回类型IO.用A型Haskell的函数makeFoo :: CInt -> CString -> Maybe Foo表示,是否Maybe FooNothing还是Just _要靠上的数值CIntCString.这一点与内部的值一样重要,Just只取决于参数.

如果可以使用相同的参数调用函数并根据现实世界的状态获得不同的结果,那么它根本不是函数,而应该是一个IO动作.