如何根据Haskell的区域设置格式化数字? [英] How to format numbers according to locale in Haskell?

查看:125
本文介绍了如何根据Haskell的区域设置格式化数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中,我可以使用 locale.format 根据区域设置漂亮地打印数字:

 >>>导入区域设置
>>> locale.setlocale(locale.LC_ALL,en_US.UTF-8)
'en_US.UTF-8'
>>> locale.format(%。2f,1234567.89,grouping = True)
'1,234,567.89'



<我怎样才能在Haskell中做同样的事情?我看到有 localeconv和setlocale 绑定,但是有一个通用的漂亮打印机,它尊重 Lconv

解决方案

我会说,如果缺少库,那么你可以自己写一个(明显的选择,不容易)或为所需的函数写一个绑定。例如, sprintf 的限制绑定仅允许sprintf加倍:

Double.hs:

  { - #INCLUDEdouble.h# - } 
{ - #LANGUAGE ForeignFunctionInterface# - }
module Double (cPrintf)其中

导入外部
导入Foreign.C.Types
导入System.IO.Unsafe
将限定的Data.ByteString导入为B

foreign import ccalldouble.h toString
c_toString :: CDouble - > (Ptr Word8) - > CInt - > IO CInt

buf = unsafePerformIO $ mallocBytes 64

cPrintf :: Double - > B.ByteString
cPrintf n = B.pack $ unsafePerformIO $ do
len< - c_toString(realToFrac n)buf 64
peekArray(fromIntegral len)buf




$ p $ $ $ $ $ $ $ $ toString(double a,char * buffer,int bufferLen);

double.c:

  #include< stdio.h> 
#includedouble.h

int toString(double a,char * buffer,int bufferLen){
return snprintf(buffer,bufferLen,%f,a );

$ / code $

$ b

构建为:

  gcc -c double.c 
ghc --make Main.hs double.o


In Python I can use locale.format to pretty-print numbers according to locale setting:

>>> import locale
>>> locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
'en_US.UTF-8'
>>> locale.format("%.2f",1234567.89,grouping=True)
'1,234,567.89'

How can I do the same in Haskell? I see that there are localeconv and setlocale bindings, but is there a generic pretty printer which respects Lconv?

解决方案

I would say that if the library in question is missing then you could either write yourself one (obvious option, not easy) or write a binding for the needed function. For example, restricted binding for sprintf which allows to sprintf only doubles:

Double.hs:

{-# INCLUDE "double.h" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Double (cPrintf) where

import Foreign
import Foreign.C.Types
import System.IO.Unsafe
import qualified Data.ByteString as B

foreign import ccall "double.h toString"
 c_toString :: CDouble -> (Ptr Word8) -> CInt -> IO CInt

buf = unsafePerformIO $ mallocBytes 64

cPrintf :: Double -> B.ByteString
cPrintf n = B.pack $ unsafePerformIO $ do
   len <- c_toString (realToFrac n) buf 64
   peekArray (fromIntegral len) buf

double.h:

int toString(double a, char *buffer, int bufferLen);

double.c:

#include <stdio.h>
#include "double.h"

int toString(double a, char *buffer, int bufferLen) {
 return snprintf(buffer, bufferLen, "%f", a);
}

Build as:

gcc -c double.c
ghc --make Main.hs double.o

这篇关于如何根据Haskell的区域设置格式化数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆